如何使用 reducer 适当地处理反应状态和专业更新
How to handle react state and pros update appropriately with reducer
我是react新手,一直在尝试用reactjs做一个设置页面。我想要实现的是,当用户第一次加载页面时,我希望从反应组件状态加载设置页面属性,因为没有任何可用设置,当用户提交数据并且第二次呈现页面时设置属性现在应该从来自 redux-saga 的道具加载。
我写的代码如下
import React, { Component } from 'react';
class Setting extends Component {
constructor(props) {
super(props)
this.state = {
settings_1: {},
settings_2: {
child_one: {
subchild_one:true,
subchild_two:true
}
}
}
}
componentDidMount() {
this.props.activateAuthLayout();
if (this.props.user !== null && this.props.user.shop_id) {
this.props.loadSettings({
payload: { ...this.props.user},
});
}
}
handleChange = (event) => {
let data = {[event.target.name]: value= [event.target.value]};
let newState = { ...this.state.settings_2.child_one, data };
this.setState({settings_2: newState });
}
render() {
if(!this.props.is_settings_loaded){
return (
<div>loading...</div>
)
}
return (
<div className="content">
<div className="custom-control custom-checkbox mb-0">
<input
type="checkbox"
className="custom-control-input"
id="checkbox1"
name="subchild_one"
checked={this.props.settings.settings_2.child_one.subchild_one || this.state.settings_2.child_one.subchild_two}
onChange={e => this.handleChange(e)}
/>
<label className="custom-control-label font-weight-normal darktextcolor" htmlFor="sync_all_product_attributes">Select All</label>
</div>
</div>
);
}
}
const mapStatetoProps = state => {
const { user } = state.Common;
const { settings, is_settings_loaded } = state.Settings;
return { user, settings, is_settings_loaded };
}
export default withRouter(connect(mapStatetoProps, { activateAuthLayout, loadSettings, updateSettings })(Setting));
一切正常,除了当道具上有可用设置并且我想取消选中该复选框时,它永远不会取消选中。我发现那是因为现在我有道具而且没有改变。我该如何处理这种情况?
我尝试使用 defaultChecked 而不是 checked 但我有 select 所有复选框,如果我使用 defaultCheck 将不起作用。
非常感谢任何类型的建议。
谢谢
关于 redux 和 react 状态
要解决的第一个问题是您正在将 redux 的状态镜像到 React 的状态。这是一个反模式,您应该遵循单一事实来源以避免差异。
修正你消耗的状态
回顾过去,您应该从 React 的状态中删除与 Redux 的状态相关的内容。然后你的 handleChange
应该使用 this.props.updateSettings
来更新你的 redux 的状态。这样,您组件中的所有数据都会正确反映出来。
对于您的 handleChange 逻辑复选框,您应该使用 属性 checked
。此外,您似乎在数据构建和 newState 上有一些错误。您正在将您的值包装到一个数组中,并且您似乎正在分配给未声明的 value
变量
你应该将下一个 redux 的状态传递给你的 updateSettings
,比如:
handleChange = (event) => {
let data = {[event.target.name]: event.target.checked};
let newState = { ...this.props.settings_2.child_one, ...data };
this.props.updateSettings(newState);
}
你的输入 name
应该是 subchild_one
而不是 child_one
,你的检查应该只指向你的道具 subchild_one
:
<input
type="checkbox"
className="custom-control-input"
id="checkbox1"
name="subchild_one"
checked={this.props.settings_2.child_one.subchild_one}
onChange={this.handleChange}
/>
我是react新手,一直在尝试用reactjs做一个设置页面。我想要实现的是,当用户第一次加载页面时,我希望从反应组件状态加载设置页面属性,因为没有任何可用设置,当用户提交数据并且第二次呈现页面时设置属性现在应该从来自 redux-saga 的道具加载。 我写的代码如下
import React, { Component } from 'react';
class Setting extends Component {
constructor(props) {
super(props)
this.state = {
settings_1: {},
settings_2: {
child_one: {
subchild_one:true,
subchild_two:true
}
}
}
}
componentDidMount() {
this.props.activateAuthLayout();
if (this.props.user !== null && this.props.user.shop_id) {
this.props.loadSettings({
payload: { ...this.props.user},
});
}
}
handleChange = (event) => {
let data = {[event.target.name]: value= [event.target.value]};
let newState = { ...this.state.settings_2.child_one, data };
this.setState({settings_2: newState });
}
render() {
if(!this.props.is_settings_loaded){
return (
<div>loading...</div>
)
}
return (
<div className="content">
<div className="custom-control custom-checkbox mb-0">
<input
type="checkbox"
className="custom-control-input"
id="checkbox1"
name="subchild_one"
checked={this.props.settings.settings_2.child_one.subchild_one || this.state.settings_2.child_one.subchild_two}
onChange={e => this.handleChange(e)}
/>
<label className="custom-control-label font-weight-normal darktextcolor" htmlFor="sync_all_product_attributes">Select All</label>
</div>
</div>
);
}
}
const mapStatetoProps = state => {
const { user } = state.Common;
const { settings, is_settings_loaded } = state.Settings;
return { user, settings, is_settings_loaded };
}
export default withRouter(connect(mapStatetoProps, { activateAuthLayout, loadSettings, updateSettings })(Setting));
一切正常,除了当道具上有可用设置并且我想取消选中该复选框时,它永远不会取消选中。我发现那是因为现在我有道具而且没有改变。我该如何处理这种情况?
我尝试使用 defaultChecked 而不是 checked 但我有 select 所有复选框,如果我使用 defaultCheck 将不起作用。
非常感谢任何类型的建议。 谢谢
关于 redux 和 react 状态
要解决的第一个问题是您正在将 redux 的状态镜像到 React 的状态。这是一个反模式,您应该遵循单一事实来源以避免差异。
修正你消耗的状态
回顾过去,您应该从 React 的状态中删除与 Redux 的状态相关的内容。然后你的 handleChange
应该使用 this.props.updateSettings
来更新你的 redux 的状态。这样,您组件中的所有数据都会正确反映出来。
对于您的 handleChange 逻辑复选框,您应该使用 属性 checked
。此外,您似乎在数据构建和 newState 上有一些错误。您正在将您的值包装到一个数组中,并且您似乎正在分配给未声明的 value
变量
你应该将下一个 redux 的状态传递给你的 updateSettings
,比如:
handleChange = (event) => {
let data = {[event.target.name]: event.target.checked};
let newState = { ...this.props.settings_2.child_one, ...data };
this.props.updateSettings(newState);
}
你的输入 name
应该是 subchild_one
而不是 child_one
,你的检查应该只指向你的道具 subchild_one
:
<input
type="checkbox"
className="custom-control-input"
id="checkbox1"
name="subchild_one"
checked={this.props.settings_2.child_one.subchild_one}
onChange={this.handleChange}
/>