简体   繁体   English

将道具转移到状态的正确方法(如果需要)React&Redux

[英]Correct Way to Transfer Props to State (if needed) React & Redux

I have created a Create-React-App react app & Redux. 我创建了一个Create-React-App react app和Redux。

I am using connect to map my userReducer to state (via mapStateToPrope) ie: 我正在使用连接将我的userReducer映射到状态(通过mapStateToPrope),即:

function mapStateToProps({ userProfile }) {
return { userProfile: userProfile ? userProfile : null };
}

export default connect(mapStateToProps, fetchUserProfile)(Profile);

and I have an input which I have binded the UserProfile Firstname to: 并且我有一个将UserProfile Firstname绑定到的输入:

render(){
   return (
    <div>
       <input type="text" value={this.props.userProfile.firstName} />
   </div>
 ) 
}

This issue is now that I have it binded to the props, I am unable to change it, If I type in the input it wont change the text inside the input.. 现在的问题是我将其绑定到道具,无法更改它,如果我输入输入内容,则不会更改输入内容。

If I add a onChange={updateValue} method, and try and update the prop it wont work as a component can not update its own props. 如果我添加了onChange = {updateValue}方法,并尝试更新道具,那么它将无法正常工作,因为组件无法更新自己的道具。

So that leaves Transfering the props to state. 这样就可以将道具转移到状态。

constructor(props){
    super(props);
    this.state = { FirstName : this.props.userProfile.firstName }
}

is this the recommended way to get an initial value from props? 这是从道具获得初始值的推荐方法吗?

You are trying to use a controlled input without providing information about updating the state. 您正在尝试使用受控输入,而没有提供有关更新状态的信息。

If you just want to provide an initial state, you could use the defaultValue property of input fields. 如果只想提供初始状态,则可以使用输入字段的defaultValue属性。

<input defaultValue={this.props.value} />

With this you could easily change the input value, without writing overhead. 这样,您可以轻松更改输入值,而无需写开销。

However, if you want to update your component, you should use the component state (like you did in your onChange example) or you use the redux state, if you want to provide the input value to more components than your input component. 但是,如果要更新组件,则应使用组件状态(就像在onChange示例中所做的那样),或者如果要向更多组件提供输入值而不是输入组件,则应使用redux状态。

const Component = ({ firstname, updateFirstname }) => (
  <input
    onChange={updateFirstname}
    value={firstname}
  />
);

const mapStateToProps = state => ({
  firstname: state.profile.firstname,
});

const mapDispatchToProps = dispatch => ({
  updateFirstname: e => dispatch({ type: 'UPDATE_FIRSTNAME', firstname: e.target.value }),
});

connect(mapStateToProps, mapDispatchToProps)(Component);

In order to have a change take place managed in either local state or redux, you want to call the function onChange as follows 为了使更改可以在本地状态或redux中进行管理,您需要按以下方式调用onChange函数

onChange={(e) => this.updateField('fieldName',e.target.value,e)}

The value field would be and would always be updated when the props (or state are updated) 当道具(或状态被更新)时,值字段将且将始终被更新。

value={this.props.fieldName}

or 要么

value={this.state.fieldName}

You onChange function would either call setState({fieldName: value}) to set local state or dispatch to redux to update the Store which is turn would update the local state via your mapStateToProps function. 您的onChange函数可以调用setState({fieldName:value})来设置本地状态,也可以分派到redux来更新Store,这将通过mapStateToProps函数来更新本地状态。

There's nothing wrong in doing that for a controlled component. 对受控组件执行此操作没有错。 But one mistake you made is there is no this.props in the constructor. 但是您犯的一个错误是,构造函数中没有this.props You're passing props directly to the constructor using the props variable. 您正在使用props变量将props直接传递给构造函数。 So the code will be 所以代码将是

this.state = {
  FirstName: props.userProfile.firstName
};

But if you want the value from the store to be updated on the component later on then do declare componentWillReceiveProps() and set the state value there also so that the changes in store are captured here. 但是,如果您希望以后在组件上更新存储中的值,则请声明componentWillReceiveProps()并在那里设置状态值,以便在此处捕获存储中的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM