我将id
数组中对象的索引(posts
)传递给要更新的状态。我能够找到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
}
}
我做错了什么?有没有其他方法来更新状态?请帮忙。
答案 0 :(得分:3)
我认为你正在改变state
中不允许的redux
尝试更改此内容:
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
确实是一个数字,而不是一个字符串。
<强>更新强>
您的初始状态是一个对象,但是当您更改状态时,您的reducer将返回一个数组
将减速器更改为:
(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>