reactjs #redux #react-redux #react-hooks
#reactjs #redux #react-redux #реагирующие хуки
Вопрос:
Я настраиваю очень простое приложение react typescript и redux. Я использовал useSelector() для получения состояния, а затем использовал его в своем компоненте. однако, когда я подключаюсь к хранилищу, добавляя новую статью, пользовательский интерфейс не меняется, я проверил redux dev tools, и хранилище обновляется, я прочитал, что useSelector автоматически подписывается на store, поэтому я не уверен, почему у меня возникла эта проблема. мой код компонента приложения:
function App() {
const dispatch: Dispatch<any> = useDispatch();
const articles: readonly IArticle[] = useSelector(
(state: ArticleState) => state.articles
);
const saveArticle = React.useCallback(
(article: IArticle) => dispatch(addArticle(article)),
[dispatch]
);
return (
<div className="App">
<header className="App-header">
<h1>My Articles</h1>
<AddArticle saveArticle={saveArticle} />
<ul>
{articles.map((article: IArticle) => (
<li>{article.title}</li>
))}
</ul>
</header>
</div>
);
}
export default App;
дополнительная статья ActionCreator
export function addArticle(article: IArticle) {
const action: ArticleAction = {
type: actionTypes.ADD_ARTICLE,
article,
};
return simulateHttpRequest(action);
}
Редуктор
const reducer = (
state: ArticleState = initialState,
action: ArticleAction
): ArticleState => {
switch (action.type) {
case actionTypes.ADD_ARTICLE:
const newState = {
...state,
};
const newArticle: IArticle = {
id: Math.random(), // not really unique
title: action.article.title,
body: action.article.body,
};
newState.articles.push(newArticle);
return newState;
case actionTypes.REMOVE_ARTICLE:
const newArticles = state.articles.filter(
(article) => article.id !== action.article.id
);
return {
...state,
articles: newArticles,
};
default:
return state;
}
};
export default reducer;
вот скриншот, на котором я вижу, что данные фактически обновляются в хранилище
Комментарии:
1. Можете ли вы показать код, который «добавляет» элемент в статьи? useSelector не сработает, если экземпляр состояния не изменился.
2. кроме того, почему вы помечаете значение как «только для чтения»?
3. @JonathanAlfaro код для добавления новой статьи — это метод saveArticle
4. нет, это не так… функция, которая сохраняет статью, называется dispatch(addArticle(статья)… итак, нам нужно увидеть код для «addArticle»
5. @JonathanAlfaro Я только что отредактировал вопрос и добавил addArticle ActionCreator
Ответ №1:
Строка newState.articles.push(newArticle);
изменяет существующий articles
массив. Затем ваш селектор пытается прочитать state.articles
. Поскольку это та же ссылка, что и раньше, React-Redux предполагает, что ничего не изменилось, и не будет повторно отображаться:
https://react-redux.js.org/api/hooks#equality-comparisons-and-updates
Пожалуйста, переключитесь на использование Redux Toolkit для настройки хранилища и логики редуктора. Это не только позволит вам упростить ваши редукторы, написав такую «мутирующую» логику и позволив ей создавать обновления неизменно, это эффективно делает случайные мутации, подобные этому, невозможными.