私は、ユーザーがそれらの投稿に回答を投稿できる投稿を持つこのWebアプリケーションを作成しています。React-Reduxを使用してアプリケーションの状態を管理しました。特定の投稿の回答を作成または更新するたびに、その投稿に属する回答のリスト全体が再レンダリングされます。それを停止して、新しく作成または更新された回答のみをレンダリングしたいと思います。コメントの投稿にもまったく同じ方法を使用しましたが、問題なく機能します。コメントは再レンダリングされませんが、回答は再レンダリングされます。ここで何が問題なのか理解できません。以下のコードを参照してください。
私React.memo()
も使ってみましたが、うまくいきません!
レンダリングコンポーネントに回答し、
export function Answer() {
const classes = useStyles();
const dispatch = useDispatch();
const { postId } = useParams();
const postAnswers = useSelector(state => state.Answers);
const [answers, setAnswers] = React.useState(postAnswers.answers);
React.useEffect(() => {
if(postAnswers.status === 'idle') dispatch(fetchAnswers(postId));
}, [dispatch]);
React.useEffect(() => {
if(postAnswers.answers) handleAnswers(postAnswers.answers);
}, [postAnswers]);
const handleAnswers = (answers) => {
setAnswers(answers);
};
const AnswersList = answers ? answers.map(item => {
const displayContent = item.answerContent;
return(
<Grid item key={item.id}>
<Grid container direction="column">
<Grid item>
<Paper component="form" className={classes.root} elevation={0} variant="outlined" >
<div className={classes.input}>
<Typography>{displayContent}</Typography>
</div>
</Paper>
</Grid>
</Grid>
</Grid>
);
}): undefined;
return(
<Grid container direction="column" spacing={2}>
<Grid item>
<Divider/>
</Grid>
<Grid item>
<Grid container direction="column" alignItems="flex-start" justify="center" spacing={2}>
{AnswersList}
</Grid>
</Grid>
<Grid item>
<Divider/>
</Grid>
</Grid>
);
}
回答を取得するreduxが適用されます。
export const fetchAnswers = (postId) => (dispatch) => {
dispatch(answersLoading());
axios.get(baseUrl + `/answer_api/?postBelong=${postId}`)
.then(answers =>
dispatch(addAnswers(answers.data))
)
.catch(error => {
console.log(error);
dispatch(answersFailed(error));
});
}
回答を投稿し、
export const postAnswer = (data) => (dispatch) => {
axios.post(baseUrl + `/answer_api/answer/create/`,
data
)
.then(response => {
console.log(response);
dispatch(fetchAnswers(postBelong)); //This is the way that I update answers state every time a new answer is created or updated
})
.catch(error => {
console.log(error);
});
}
どんな助けでも素晴らしいでしょう。ありがとうございました!
私はちょうど問題が上記の質問につながった場所を見つけました。私の状態管理システムには、answers
以下のような投稿回答の状態を処理するための名前のアクションがあります。
import * as ActionTypes from '../ActionTypes';
export const Answers = (state = {
status: 'idle',
errMess: null,
answers: []
}, action) => {
switch(action.type) {
case ActionTypes.ADD_ANSWER_LIST:
return {...state, status: 'succeeded', errMess: null, answers: action.payload}
case ActionTypes.ANSWER_LIST_LOADING:
return {...state, status: 'loading', errMess: null, answers: []}
case ActionTypes.ANSWER_LIST_FAILED:
return {...state, status: 'failed', errMess: action.payload, answers: []}
default:
return state;
}
}
ここでの問題は、私が入れた空の配列ANSWER_LIST_LOADING
とANSWER_LIST_FAILED
ケースです。アクション作成者が新しいデータをフェッチするたびに、loading
状態を通過し、空の配列を取得します。これにより、回答のリスト全体が再レンダリングされ、不必要に再作成されます。そこで、実装を次のように変更し、問題を修正しました。
export const Answers = (state = {
status: 'idle',
errMess: null,
answers: []
}, action) => {
switch(action.type) {
case ActionTypes.ADD_ANSWER_LIST:
return {...state, status: 'succeeded', errMess: null, answers: action.payload}
case ActionTypes.ANSWER_LIST_LOADING:
return {...state, status: 'loading', errMess: null, answers: [...state.answers]}
case ActionTypes.ANSWER_LIST_FAILED:
return {...state, status: 'failed', errMess: action.payload, answers: [...state.answers]}
default:
return state;
}
}
いつも問題は私がそうなるとは思っていなかった場所にありました。action
私の質問では、これについても言及していません。しかし、そこに行きます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加