簡體   English   中英

如何更新reducer的狀態?

[英]How to update the state of reducer?

我在要更新的狀態下在posts數組中傳遞對象的索引( id )。 我可以使用findIndex查找元素的索引並更改number鍵。 我不知道如何將更新的object傳遞回狀態/數組。

我的減速機:

const initialState = {
    posts: [
      {id:1, name:'post1', number:11},
      {id:2, name:'post2', number:22},
      {id:3, name:'post3', number:33}
   ]
}

export default function newData (state = initialState, action) {

  switch (action.type) {

    case "updateNumber": {

   // find object to update
    const index = state.posts.findIndex(({ id }) => id === action.payload);

    if (index > -1 ) {
      const toIncrement = state.posts[index];
      const number = toIncrement.number++;

      // create new object with existing data and newly incremented number
      const updatedData = { ...toIncrement, number };

      // return new array that replaces old object with incremented object at index
     // the state is not getting updated with the following:

      return [...state.posts.slice(0, index), updatedData, ...state.posts.slice(index + 1)];

    }

      // return state if no object is found
      return state;
    }

  default:
    return state
  }
}

我究竟做錯了什么? 還有其他方法可以更新狀態嗎? 請幫忙。

我認為您正在變異redux不允許的state
嘗試更改此:

if (index > -1 ) {
      const toIncrement = state.posts[index];
      const number = toIncrement.posts.number++;  

對此:

if (index > -1 ) {
      const toIncrement = {...state.posts[index]};
      const number = toIncrement.posts.number + 1;

順便說一句,請確保posts.number是真正的數字,而不是字符串。

更新
您的初始狀態是一個對象,但是當您更改狀態時,reduce會返回一個數組。
將您的減速器更改為此:

(state = initialState, action) => {
  switch (action.type) {
    case "updateNumber": {
      // find object to update
      const index = state.posts.findIndex(({ id }) => id === action.payload);
      if (index > -1) {
        const toIncrement = state.posts[index];
        const number = toIncrement.number + 1; // don't mutate the object with ++

        // create new object with existing data and newly incremented number
        const updatedData = { ...toIncrement, number };

        // return new array that replaces old object with incremented object at index
        // the state is not getting updated with the following:
        return { // this should be an object with a key of posts
          posts: [
          ...state.posts.slice(0, index),
          updatedData,
          ...state.posts.slice(index + 1)
        ]};
      }

      // return state if no object is found
      return state;
    }

    default:
      return state;
  }
};

這是您的代碼的工作示例:

 const {createStore} = Redux; const initialState = { posts: [ { id: 1, name: "post1", number: 11 }, { id: 2, name: "post2", number: 22 }, { id: 3, name: "post3", number: 33 } ] }; const newData = (state = initialState, action) => { switch (action.type) { case "updateNumber": { // find object to update const index = state.posts.findIndex(({ id }) => id === Number(action.payload)); if (index > -1) { const toIncrement = state.posts[index]; const number = toIncrement.number + 1; // create new object with existing data and newly incremented number const updatedData = { ...toIncrement, number }; // return new array that replaces old object with incremented object at index // the state is not getting updated with the following: return { posts: [ ...state.posts.slice(0, index), updatedData, ...state.posts.slice(index + 1) ] }; } // return state if no object is found return state; } default: return state; } }; const store = createStore(newData); const Posts = ({ data }) => { //debugger return ( <ul> {data.posts.map(post => ( <li>{`Number - ${post.number} | Id - ${post.id}`}</li> ))} </ul> ); }; class App extends React.Component { constructor(props) { super(props); this.state = { currentId: 1 }; } handleInputChange = e => this.setState({ currentId: e.target.value }); onClick = () => { const { currentId } = this.state; store.dispatch({ type: "updateNumber", payload: currentId }); }; render() { return ( <div> <input type="text" value={this.state.currentId} onChange={this.handleInputChange} /> <button onClick={this.onClick}>Change By Id</button> <Posts data={this.props.data} /> </div> ); } } const render = () => { ReactDOM.render( <App data={store.getState()} />, document.getElementById("root") ); }; render(); store.subscribe(render); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.6/react-redux.min.js"></script> <div id="root"></div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM