[英]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.