React 组件不在 redux 状态更新时更新
React component not updating on redux state update
我正在为我的项目使用 react、redux 和 redux-saga。在使用 Redux-saga 获取用户列表时,我可以看到我的 redux 存储正在更新(我可以从 redux 开发工具中看到),但是在组件中,道具没有改变。
我正在使用按钮获取用户列表。并且用户仅出现在该组件中。
App.js
import React, { Component } from 'react';
import { connect } from "react-redux";
import './App.css';
import { fetchUsers } from "./actions";
import { Row, Col, ListGroup, ListGroupItem } from "reactstrap";
class App extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props){
super(props);
}
render() {
console.log("in render func");
console.log(this.props);
return (
<div className="App">
<h2>Redux Saga App</h2>
<Row>
<Col sm={6}>
{this.props.userList?this.props.userList.map((user)=>(
user.first_name + user.last_name
)) : ''}
</Col>
</Row>
<button onClick={this.props.getUserList}>Click to get the users</button>
</div>
);
}
}
const mapStateToProps = (state)=>{
console.log("in map statetpprop");
//console.log(state.userList);
return {userList:state.userList}
}
const mapDispatchToProps = (dispatch)=>{
return {getUserList :() => {dispatch(fetchUsers())}}
}
App = connect(mapStateToProps,mapDispatchToProps)(App);
export default App;
action.js
export function fetchUsers(){
return {
type:'FETCH_USERS',
}
}
reducer.js
const initialState = {
userList:[]
}
export function userReducer(state=initialState,action){
switch(action.type){
case 'ADD_USER':
return Object.assign(state,{
user:action.data
})
case 'SET_USERS':
return Object.assign(state, {userList : action.data});
default:
return state;
}
}
saga.js
import {call, put , takeEvery , takeLatest } from 'redux-saga/effects';
import axios from 'axios';
import { setUsers } from "./actions";
export function fetchUsersFunc(userId){
return axios.get('https://reqres.in/api/users');
}
function* fetchUsers(action){
const users = yield call(fetchUsersFunc);
console.log("in fetch users");
if(users.data.data){
const userList = users.data.data;
console.log(userList);
console.log(userList[0].first_name)
yield put(setUsers(userList));
}
}
export function* rootSaga(){
yield [
takeLatest('FETCH_USERS',fetchUsers)
];
}
感谢您的帮助!
如果你使用 Object.assign
并且你想制作一个新的状态副本,你需要将目标对象制作成一个新的空对象而不是你当前正在做的事情(它改变了 state
对象,这使得反应无法重新渲染)。 (关于Object.assign
的更多信息可以参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)例如:
// copy previous state and new updates to a new empty object
return Object.assign({}, state, {userList : action.data});
不过我建议使用展开运算符而不是 Object.assign
:
return {...state, userList : action.data}
如果状态已更新但 UI 未更新,则表示 reducer
出现问题。
- 结帐
reducer
功能仔细。
- 如果您在
reducer
函数中使用扩展运算符 (...
),请确保在扩展运算符之后明确提及更新的数据。
工作reducer函数的例子如下:
const UvNumberReducer = (state=initialState, action: UVAction) => {
switch(action.type) {
case UV_NUMBER.LOAD:
return {
...state,
data: {
title: action.data.title,
subtitle: action.data.subtitle
}
}
default:
return state;
}
}
我正在为我的项目使用 react、redux 和 redux-saga。在使用 Redux-saga 获取用户列表时,我可以看到我的 redux 存储正在更新(我可以从 redux 开发工具中看到),但是在组件中,道具没有改变。
我正在使用按钮获取用户列表。并且用户仅出现在该组件中。
App.js
import React, { Component } from 'react';
import { connect } from "react-redux";
import './App.css';
import { fetchUsers } from "./actions";
import { Row, Col, ListGroup, ListGroupItem } from "reactstrap";
class App extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props){
super(props);
}
render() {
console.log("in render func");
console.log(this.props);
return (
<div className="App">
<h2>Redux Saga App</h2>
<Row>
<Col sm={6}>
{this.props.userList?this.props.userList.map((user)=>(
user.first_name + user.last_name
)) : ''}
</Col>
</Row>
<button onClick={this.props.getUserList}>Click to get the users</button>
</div>
);
}
}
const mapStateToProps = (state)=>{
console.log("in map statetpprop");
//console.log(state.userList);
return {userList:state.userList}
}
const mapDispatchToProps = (dispatch)=>{
return {getUserList :() => {dispatch(fetchUsers())}}
}
App = connect(mapStateToProps,mapDispatchToProps)(App);
export default App;
action.js
export function fetchUsers(){
return {
type:'FETCH_USERS',
}
}
reducer.js
const initialState = {
userList:[]
}
export function userReducer(state=initialState,action){
switch(action.type){
case 'ADD_USER':
return Object.assign(state,{
user:action.data
})
case 'SET_USERS':
return Object.assign(state, {userList : action.data});
default:
return state;
}
}
saga.js
import {call, put , takeEvery , takeLatest } from 'redux-saga/effects';
import axios from 'axios';
import { setUsers } from "./actions";
export function fetchUsersFunc(userId){
return axios.get('https://reqres.in/api/users');
}
function* fetchUsers(action){
const users = yield call(fetchUsersFunc);
console.log("in fetch users");
if(users.data.data){
const userList = users.data.data;
console.log(userList);
console.log(userList[0].first_name)
yield put(setUsers(userList));
}
}
export function* rootSaga(){
yield [
takeLatest('FETCH_USERS',fetchUsers)
];
}
感谢您的帮助!
如果你使用 Object.assign
并且你想制作一个新的状态副本,你需要将目标对象制作成一个新的空对象而不是你当前正在做的事情(它改变了 state
对象,这使得反应无法重新渲染)。 (关于Object.assign
的更多信息可以参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)例如:
// copy previous state and new updates to a new empty object
return Object.assign({}, state, {userList : action.data});
不过我建议使用展开运算符而不是 Object.assign
:
return {...state, userList : action.data}
如果状态已更新但 UI 未更新,则表示 reducer
出现问题。
- 结帐
reducer
功能仔细。 - 如果您在
reducer
函数中使用扩展运算符 (...
),请确保在扩展运算符之后明确提及更新的数据。
工作reducer函数的例子如下:
const UvNumberReducer = (state=initialState, action: UVAction) => {
switch(action.type) {
case UV_NUMBER.LOAD:
return {
...state,
data: {
title: action.data.title,
subtitle: action.data.subtitle
}
}
default:
return state;
}
}