[英]React not rerendering after action
我有一个应用程序,它有一个包含汤列表的仪表板。 每一种汤都有成为日常汤的能力。 所以每个汤都有一个按钮,如果点击它,会触发一个动作来更新我的 MongoDB,使汤成为每日汤。 当汤是日常汤时,它有 3 个按钮:删除、低、退出。 如果单击这些按钮中的任何一个,它们会触发更新我的 MongoDB 以更新该特定汤的操作。 我遇到的问题是,当单击这些按钮中的任何一个时,它会执行操作,但不会在屏幕上重新呈现。 我必须手动刷新页面才能看到它确实有效。
注意:我正在使用 reduxThunk 立即分派动作(见下面的代码)
我试过使用
Object.assign({}, state, action.payload)
在我的减速器中一定要避免直接改变状态。
我还尝试用以下方法重写我的减速器:
case "UPDATE_SOUP":
return {
...state,
isDaily: action.payload.isDaily,
isLow: action.payload.isLow,
isOut: action.payload.isOut
};
反应汤组件:
class Soup extends Component {
render() {
const { soup } = this.props;
return (
<div>
<div key={soup.name} className="card">
<div
className={`card-header ${
soup.isDaily ? "alert alert-primary" : null
}`}
>
{soup.isDaily ? (
<span className="badge badge-primary badge-pill">Daily Soup</span>
) : (
"Soup"
)}
</div>
<div className="card-body">
<h5 className="card-title">{soup.name}</h5>
<p className="card-text">
{soup.isLow ? (
<span className="badge badge-warning badge-pill">
This soup is marked as LOW.
</span>
) : null}
{soup.isOut ? (
<span className="badge badge-dark badge-pill">
This soup is marked as OUT.
</span>
) : null}
</p>
{soup.isDaily ? (
<div>
<button
onClick={() =>
this.props.updateSoup(soup._id, {
isDaily: false,
isLow: false,
isOut: false
})
}
className="btn btn-danger "
>
Remove
</button>
<button
onClick={() =>
this.props.updateSoup(soup._id, {
isLow: true
})
}
className="btn btn-warning"
>
Getting Low
</button>
<button
onClick={() =>
this.props.updateSoup(soup._id, {
isOut: true
})
}
className="btn btn-dark"
>
Ran Out
</button>
</div>
) : (
<button
onClick={event =>
this.props.updateSoup(soup._id, {
isDaily: true
})
}
className="btn btn-primary"
>
Make Daily
</button>
)}
</div>
</div>
</div>
);
}
}
function mapStateToProps({ soupsReducer }) {
return { soupsReducer };
}
export default connect(
mapStateToProps,
actions
)(Soup);
React SoupList 组件(显示所有汤):
class SoupList extends Component {
componentDidMount() {
this.props.allSoups();
}
renderSoup() {
const { soupsReducer } = this.props;
if (soupsReducer.length > 0) {
return soupsReducer.map(soup => {
if (soup.name !== "date") {
return <Soup key={soup._id} soup={soup} />;
} else {
return null;
}
});
}
}
render() {
console.log("SoupListProps=", this.props);
return <div>{this.renderSoup()}</div>;
}
}
function mapStateToProps({ soupsReducer, dateReducer }) {
return { soupsReducer, dateReducer };
}
export default connect(
mapStateToProps,
actions
)(SoupList);
行动:
export const updateSoup = (id, update) => async dispatch => {
const res = await axios.put(`/api/allsoups/${id}`, update);
dispatch({ type: "UPDATE_SOUP", payload: res.data });
};
减速器:
export default function(state = [], action) {
switch (action.type) {
case "FETCH_SOUPS":
return action.payload;
case "ALL_SOUPS":
return action.payload;
case "UPDATE_SOUP":
return action.payload;
default:
return state;
}
}
问题是你正在通过做
return action.payload;
你需要做类似的事情
return { ...state, someStateKey: action.payload.data.someKey }
根据操作类型,您从响应中提取所需数据并将其设置为您的状态。
如果您可以提供有关回复的更多信息,我可以使用更具体的详细信息更新答案
我的想法围绕着你代码的这一部分......
export const updateSoup = (id, update) => async dispatch => {
const res = await axios.put(`/api/allsoups/${id}`, update);
dispatch({ type: "UPDATE_SOUP", payload: res.data });
};
export default function(state = [], action) {
// ...code...
case "UPDATE_SOUP":
return action.payload;
// ...code...
}
}
尝试这个:
确定汤类型和你的行动的变化......
dispatch({ type: "UPDATE_SOUP", payload: res.data, souptype: id, update: update });
将状态更新为您的减速器的汤类型...
export default function(state = [], action) {
case "UPDATE_SOUP":
const newstate = action.payload;
neswstate.soups[action.souptype] = action.isDaily ? true : false;
return newstate;
当然,为什么这行不通? 仅仅是因为我在猜测您处于哪种状态以及如何在这种状态下储存汤。 您的代码中没有构造函数或状态定义,因此,您需要调整上面的内容以匹配您的状态定义方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.