简体   繁体   English

React Components状态与道具动态输入

[英]React Components state vs props Dynamic Input

I have been experimenting couple of days with ReactJS and ES6 and created couple of components ie <InputText /> , <InputNumber /> , <InputEmail /> , that are being used in the component <ContactsEdit /> . 我已经使用ReactJS和ES6进行了几天的实验,并创建了两个组件,即<InputText /><InputNumber /><InputEmail /> ,这些组件正在组件<ContactsEdit />

It seems really strange that even though I have read many tutorials my child components refuse to render() the {this.state.Firstname} even though I tried componentWillMount , componentDidMount , this.setState , this.state with this.forceUpdate() , but they will render fine the this.props.Firstname 即使我已经阅读了很多教程,但即使我尝试了componentWillMountcomponentDidMountthis.setStatethis.statethis.forceUpdate() ,即使我阅读了许多教程,我的子组件也拒绝render() {this.state.Firstname} ,但它们会很好地呈现this.props.Firstname

I would welcome any kind of suggestions or help. 我欢迎任何建议或帮助。 The source can be found at github 源码可以在github上找到

Thanks :) 谢谢 :)

` export default class ContactsEdit extends React.Component { `导出默认类ContactsEdit扩展了React.Component {

constructor(props) {
    super(props);

    this.contactId = this.props.params.id;
    this.persistence = new Persistence('mock');

    this.state = {
        contact : {}
    };

}

componentDidMount() {
    this.persistence.getContactById( this.contactId ).then( (resolve) => {
        this.setState({ contact : resolve.data });
        this.data = resolve.data;
    }).catch( (reject) => {
        console.log(reject);
    }) ;

    this.forceUpdate();
}

onChange(id,newValue)  {
    this.state.contact[ id ] = newValue;
    this.forceUpdate();
}

saveRecord( object ) {
    console.log( this.state );
}

render() {
    return (            
        <div className="ContactsEdit">
            <h2>Contact Edit (Parent) id : {this.props.params.id}, FullName : {this.state.contact.Firstname} {this.state.contact.Lastname}</h2>
            <div className="row">                    
                <InputText id="Firstname" fieldName={this.state.contact.Firstname}  labelName="Firstname" onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="Lastname"  fieldName={this.state.contact.Lastname}  labelName="Lastname"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="SocSecId"  fieldName={this.state.contact.SocSecId}  labelName="SocSecId"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="DriverLicId"  fieldName={this.state.contact.DriverLicId}  labelName="DriverLicId"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
            </div>

        </div>
    )
}

} }

` `

` export default class InputText extends React.Component { `导出默认类InputText扩展了React.Component {

constructor(props) {
    super(props);         
    this.state = { fieldName : this.props.fieldname}; 
}

componentWillMount() {
    //this.state.fieldName = this.props.fieldname;
    //this.forceUpdate();
}

updateState(evt) {
    //this.setState( {fieldName : evt.target.value} );
    this.props.onChange( evt.target.id, evt.target.value     );
}

render() {
    return (
        <div className={this.props.divClass}>
            <hr />
            <label> {this.props.labelName} </label>
            <div>{this.props.fieldName}</div> 
            <div>{this.state.fieldName}</div> 
            <input 
                type="text" 
                id={this.props.id} 
                value={this.props.fieldName} 
                onChange={this.updateState.bind(this)} 
                className="form-control"
            />
        </div>
    )
}

} ` }`

this.props doesn't exist in the constructor function until after its run, binding this to an instance of the class. this.props不会在构造函数中存在,直到其运行后,结合this的类的实例。 Use the props that are passed in from the parent (in the argument) 使用从父级传入的props (在参数中)

constructor (props) {
    super(props)
    this.state = { fieldName: props.fieldname }
}

componentWillMount is replaced by using ES6 class constructor 使用ES6类构造函数替换componentWillMount

Also you should not modify this.state directly. 同样,您不应该直接修改this.state It won't cause react to call render() . 调用render()不会引起反应。 Only set the initial state in constructor. 仅在构造函数中设置初始状态。 Everywhere else, call this.setState({ data: newData }) . 在其他任何地方,调用this.setState({ data: newData })

The reason I am posting the topic and the GitHub link is that I have tried everything. 我发布主题和GitHub链接的原因是我已经尝试了一切。 I know that using this.state is not best practice and I have used it in conjuction with this.forceUpdate because the this.setState() would not work. 我知道使用this.state并不是最佳实践,并且已与this.forceUpdate结合使用,因为this.setState()无法正常工作。

I am also aware that componentWillUpdate() has been replaced in ES6 but removing it and only using the constructor() wouldn't do the job for me. 我也知道在ES6中已经替换了componentWillUpdate() ,但是将其删除并且仅使用constructor()不会对我有用。

I have also tried 我也尝试过

constructor(props) {
    super(props);
    this.setState({ fieldName : 'something' })
// …

but that only led to hardcoding the value into my component. 但这只会导致将值硬编码到我的组件中。 I have tried returning the value using a promise: 我试过使用Promise返回值:

constructor(props) {
    super(props);

    MyPromise( (resolve) => {
       this.setState({ fieldName : resolve})
    }
// …

but that did not work either. 但这也不起作用。

So I started wondering if maybe there is something wrong with my gulpfile (thus providing the GitHub repo so someone with more expertise could maybe check and help). 因此,我开始怀疑gulpfile是否存在问题(因此提供了GitHub存储库,以便有更多专业知识的人可以检查和帮助)。

Very strangely, though, the this.props solution worked even though I understand it's not the best practice. 但是,很奇怪的是,即使我了解这不是最佳实践, this.props解决方案仍然有效。

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

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