[MONDEUK開発7~12日目①]執筆機能を実現
14748 ワード
💡 緒論
最近ブログ開発ログをきちんと書いていません.
理由は….個人は多くの苦しい仕事を経験した.ははは
だから開発の面でも大きな障害を受け、人も低迷に陥った.
もちろん最后に、すぐに解决しましたが!!
現在、低迷は予想されません:)
だからこの間はちゃんと開発していなかったことを今回書きます.
🔍 本題
まず書くスキルです
実際には
XSS
の攻撃を予防するために仕事が必要ですまず機能を実現する目標を設定したので、本当に機能を実現しました!
書く上では、大きく分けて以下の点があります.
title
値body
値Tags
値WriteReducer
として処理して状態管理を行う.1~2. Components/ WriteForm.js(styled-connts省略)
まずは書く部分!
まずここでは簡単な伝達値を設定します.
const WriteForm = ({ onChangeText, title, body }) => {
const onChange = (e) => {
const { name, value } = e.target;
onChangeText({name, value});
};
return (
<>
<StyledTitleText onChange={onChange} name="title" value={title} />
<StyledBodyText onChange={onChange} name="body" value={body} text/>
</>
);
};
export default WriteForm;
2. Components/ TagBar.js
2つ目はラベルを渡すTagBarです
ここはちょっと複雑で、
まず、
Tag
の生成において、全体Tags
の生成を継続する現象が現れる.これは、関数が再レンダリングされ続けるためです.そこで、関数が再レンダリングされないように
useCallback
を作成しました.まだ詳細なデザインはありませんが、クリック時にラベルを削除する機能が追加されました!
const TagBar = ({ onChangeTags, tags }) => {
const [ input, setInput ] = useState('');
const [ nowTags, setNowTags ] = useState([]);
const insertTag = useCallback(
tag => {
if ((!tag) || (nowTags.includes(tag))) return;
const addedTag = [...nowTags, tag];
setNowTags(addedTag);
onChangeTags(addedTag);
},
[onChangeTags, nowTags]);
const onChange = useCallback(e => {
setInput(e.target.value);
},[]);
const onSubmit = useCallback(e => {
e.preventDefault();
insertTag(input.trim());
setInput('');
},[input, insertTag]);
const onRemove = useCallback(
tag => {
const filteredTags = nowTags.filter(now => now !== tag);
setNowTags(filteredTags);
onChangeTags(filteredTags);
}, [onChangeTags, nowTags]
)
return (
<StyledTagBar>
<StyledTagsForm onSubmit={onSubmit}>
<StyledTagsInput onChange={onChange} value={input} />
<StyledTagsBtn type="submit">등록</StyledTagsBtn>
</StyledTagsForm>
<TagsWrapper tags={nowTags} onRemove={onRemove}></TagsWrapper>
</StyledTagBar>
);
};
export default TagBar;
3. Components/PostDiaryBtnsWrapper.js
const PostDiaryBtnsWrapper = ({ onPostDairy, onCancel }) => {
return (
<StyledPostDiaryBtnsWrapper>
<StyledPostDiaryBtn onClick={onPostDiary}>일기 올리기</StyledPostDiaryBtn>
<StyledPostDiaryBtn onClick={onCancel}>작성 취소</StyledPostDiaryBtn>
</StyledPostDiaryBtnsWrapper>
);
};
export default PostDiaryBtnsWrapper;
日記帳をアップロードするためのボタンは簡単です.ステータス値がcontainer
からmodule
まで取得されると、その実現機能は終了する.container
は、全体としてaction
をdispatch
に変換した後、サブアセンブリに変換する.containers/ WriteFormContainer.js
import React, { useCallback, useEffect } from 'react'
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux';
import WriteBackground from '../../../components/write/WriteBackground';
import WriteForm from '../../../components/write/WriteForm';
import { changeText, initializeDiary } from '../../../modules/write';
function WriteFormContainer() {
const { title, body } = useSelector(({ writeReducer }) => ({
title: writeReducer.title,
body: writeReducer.body
}));
const dispatch = useDispatch();
const onChangeText = useCallback(payload => dispatch(changeText(payload)),[dispatch]);
useEffect(() => {
dispatch(initializeDiary());
}, [dispatch])
return (
<>
<WriteBackground>
<WriteForm onChangeText={onChangeText} title={title} body={body}></WriteForm>
</WriteBackground>
</>
)
}
export default WriteFormContainer
containers/ TagBarContainer.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux';
import TagBar from '../../../components/write/TagBar';
import { changeText } from '../../../modules/write';
function TagBarContainer() {
const dispatch = useDispatch();
const tags = useSelector(({writeReducer}) => ({tags: writeReducer.tags}));
const onChangeTags = tags => {
dispatch(changeText({ name: "tags", value: tags }));
}
return (
<TagBar onChangeTags={onChangeTags} tags={tags} />
)
}
export default TagBarContainer
containers/ PostDiaryBtnsWrapperContainer.js
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { withRouter } from 'react-router';
import PostDiaryBtnsWrapper from '../../../components/write/PostDiaryBtnsWrapper';
import { writeDiary } from '../../../modules/write';
function PostDiaryBtnsWrapperContainer({ history }) {
const dispatch = useDispatch();
const { title, body, tags, diary, writeError } = useSelector(({ writeReducer }) => ({
title: writeReducer.title,
body: writeReducer.body,
tags: writeReducer.tags,
diary: writeReducer.diary,
writeError: writeReducer.writeError
}))
const onPostDiary = () => {
dispatch(writeDiary({title, body, tags}))
};
const onCancel = () => {
history.goBack();
};
useEffect(() => {
if (writeError) console.error(writeError)
if (diary) {
console.log(diary)
const { _id, author } = diary;
console.log(author);
history.push(`/@${author.userId}/${_id}`);
};
}, [writeError, diary, history])
return (
<PostDiaryBtnsWrapper onPostDiary={onPostDiary} onCancel={onCancel}/>
)
}
export default withRouter(PostDiaryBtnsWrapperContainer)
最後はmodule
!module/diary.js
import { createAction, handleActions } from 'redux-actions';
import createActionTypes from '../lib/createActionTypes';
import createSaga from '../lib/createSaga';
import writeAPI from '../lib/routes/post/write';
import {takeLatest} from 'redux-saga/effects';
const CHANGE_TEXT = 'write/CHANGE_TEXT';
const INITIALIZE_DIARY = 'write/INITIALIZE_DIARY';
const WRITE_DIARY = 'write/WRITE_DIARY';
const [ WRITE_DIARY_SUCCESS, WRITE_DIARY_FAILURE ] = createActionTypes(WRITE_DIARY);
export const changeText = createAction(CHANGE_TEXT, ({ name, value }) => ({
name,
value,
}));
export const initializeDiary = createAction(INITIALIZE_DIARY, diary => diary)
export const writeDiary = createAction(WRITE_DIARY, ({ title, body, tags }) => ({
title, // diary title
body, // diary content
tags, // diary tags
}));
const writeDiarySaga = createSaga(WRITE_DIARY, writeAPI);
export function* writeSaga() {
yield takeLatest(WRITE_DIARY, writeDiarySaga);
}
const initialState = {
title: '',
body: '',
tags: [],
writeError: '',
diary: '',
};
const writeReducer = handleActions({
[CHANGE_TEXT]: (state, { payload: {name, value} }) => ({
...state,
[name]: value
}),
[INITIALIZE_DIARY]: state => initialState,
[WRITE_DIARY]: state => ({
...state,
diary: null,
writeError: null,
}),
[WRITE_DIARY_SUCCESS]: (state, { payload: diary }) => ({
...state,
diary,
}),
[WRITE_DIARY_FAILURE]: (state, { payload: writeError }) => ({
...state,
writeError,
})
}, initialState)
export default writeReducer
このようにした結果.とても美しい(??)デザインのライティング機能が完成~
実は、
useCallback
とmap
のため、私は自分が2日連続で髪を結っていたことを覚えています.でも結局は機能を実現してこそ意味があるんですね~😁👍👏
話が戻る.溜まった日記がいつ書けるか心配です.😂😂😂
Reference
この問題について([MONDEUK開発7~12日目①]執筆機能を実現), 我々は、より多くの情報をここで見つけました https://velog.io/@jengyoung/MOONDEUK-개발-12일차-글쓰기-기능-다이어리-읽기-기능-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol