reactjs - 为什么在 React-Redux 中更改时一种状态会影响另一种状态?

标签 reactjs redux

我是 Redux 新手。我有一个问题,我制作了一个简单的 Redux 应用程序,具有两个不同的功能,一个是基于计数的增量减量,第二个是单击按钮然后更改图像,所以我真正的问题是当我首先更新状态增量减量然后工作正常但如果我按下按钮单击然后再次按下增量或减量按钮然后在增量减量结果的位置显示错误 NAN 1 2 0r 其他并在控制台中显示以下错误:

Received NaN for the `children` attribute. If this is expected, cast the value to a string.

“我尝试了很多方法,例如以多种不同的方式调度操作,但在任何情况下都不适合我。”

请检查代码并指导我

常量.js

export const CLICK_ME = 'CLICK_ME'
export const INCREMENT  = 'INCREMENT'
export const DECREMENT = 'DECREMENT'

action.js

import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'

export const clicking = () => {
  return {
    type:CLICK_ME
  }
}

export const increment =()=>{
  return {
    type : INCREMENT
  }
}


export const decrement =()=>{
  return {
    type : DECREMENT
  }
}

reducer .js

import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'

const initialState = {
  click : true,
  count: 0
}

const reducer = (state = initialState , action) => {
  if(action.type === CLICK_ME){
    return {click : !state.click}
  }
  else if(action.type === INCREMENT ){
    return { count: state.count + 1  }
  }
  else if(action.type === DECREMENT ){
    return {  count: state.count - 1  }
  }
  else return state
}

export default reducer

store.js

import reducer from '../reducers/reducer'
import { createStore } from 'redux'

const store = createStore(reducer)
export default store

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.css'
import store from './store/store'
import { Provider } from 'react-redux'
ReactDOM.render(
    <Provider  store={store} >
        <App />
    </Provider>
  , document.getElementById('root'));
serviceWorker.unregister();

App.js

import React from 'react';

import {connect} from 'react-redux'
import { CLICK_ME, INCREMENT, DECREMENT } from './constant/constant';
function App(props) {
  return (
    <div className="container pt-5 mt-5 ">
        <div className="row">
          <div className="col col-sm-8 col-md-8 col-lg-8 col-xl-8 ">
            { props.click ?  <img src="data:image/jpeg;base64,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" className="img-fluid rounded-circle" width="30%" height="auto" alt=""/> : <img  src="https://cdn2.iconfinder.com/data/icons/user-needs-19/16/45_false_delete_remove_cross_wrong_2-512.png"  className="img-fluid rounded-circle" alt=""  width="30%" height="auto" />}  
          </div>
          <div className="col col-sm-4 col-md-4 col-lg-4 col-xl-4 ">
              <p className="text-danger" >THE NUMBER IS COUNT ON EVERY CLICK </p>
              <code className="p-5 " style={{fontSize:"100px"}} >{props.count}</code>
          </div>
        </div>
        <hr className="bg-info p-1 m-1" />
       <button className="btn btn-danger m-1" onClick={props.increment} >Increment</button> 
       <button className="btn btn-danger m-1" onClick={props.decrement} >Decrement</button>
      <button className="btn btn-primary bg-info float-right" onClick={props.clicks} >Click me to change the state</button>
    </div>
  );
} 

const mapStateToProps = (state)=>{
    return {
      click : state.click,
      count : state.count
    }
}
const dispatchToProps = (dispatch) => {

  return  { 
    clicks:()=>dispatch({type:CLICK_ME}),
    increment :()=>dispatch({type:INCREMENT}),
    decrement :()=>dispatch({type:DECREMENT})
  }

}

export default connect(mapStateToProps,dispatchToProps)(App)

最佳答案

您缺少的关键是您需要从您的 reducer 函数返回整个状态,而不仅仅是您使用该操作修改的部分。这意味着复制您未修改的属性。

按如下方式更改您的 reducer 函数(我还建议您使用 switch 语句,这样可以减少打字量并与其他 Redux 代码保持一致):

import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'

const initialState = {
  click : true,
  count: 0
}

const reducer = (state = initialState , action) => {
  switch (action.type) {
    case CLICK_ME:
      return { ...state, click: !state.click };
    case INCREMENT:
      return { ...state, count: state.count + 1 };
    case DECREMENT:
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}

export default reducer;

如果您不熟悉它,...state 使用对象传播运算符,该运算符从 复制所有属性及其值状态到新对象上。或者,您可以使用等效的 Object.assign({}, state, {modified: 'state' })

关于reactjs - 为什么在 React-Redux 中更改时一种状态会影响另一种状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57433483/

相关文章:

javascript - 循环遍历多个项目并渲染每个项目

reactjs - REACT JSX 样式 [对象对象]

javascript - 无法裁剪图像,错误为 : failed to compile fragment shader Tensorflow. js

javascript - 使用 Immutable JS 映射时如何设置多个对象值

javascript - Redux状态树结构: "same type of data with different format/amounts of detail"

javascript - 当时间是午夜时更新日期和时间

html - 如何在两个组件之间画线

javascript - 在 react 路由器中的路由之间显示一个简单的加载指示器

reactjs - 将 redux 与本地数据库结合使用

unit-testing - 通过 jest mock 测试 catch block