首页 > 解决方案 > 从 componentDidMount 调用时,setstate 不会重新渲染子组件

问题描述

我有一个要设置的父组件

interface SignUpPropModel {}
interface SignUpState{
    form:(InputProps&{desc: string})[];
}
export class SignUp extends Component<SignUpPropModel, SignUpState > {
    state: SignUpState = {
        form:[]
    }
    constructor(props:SignUpPropModel){
        super(props)
        this.state.form = [{
                type:"text",
                classnames:"form-control",
                id: "username",
                name: "username",
                isvalid: false,
                placeholder:"Username",
                value:'',
                desc:'Username'
            }]            
    }
    componentDidMount() {
            let form = [...this.state.form];
            if(form){
                form[0].isvalid=false;
                this.setState({form: form});
            }  
    }
    render(){
        return (
                    <form className='my-3'>
                        {this.state.form?.map((inputProps) => ( 
                                    <div key={inputProps.id} className="form-group mx-3" >
                                        <label htmlFor={inputProps.id}>{inputProps.desc}</label>
                                        <Input  {...inputProps}/>
                                    </div>)) }
                    </form>
        );
    }
}

输入组件 -

interface IProps{
    type:'text'|'checkbox'|'radio'|'password';
    value?: any;
    name?: string;
    id?:string;
    onClick?: ((event: React.MouseEvent<HTMLInputElement, MouseEvent>) => void);
    onChange?:((event: React.ChangeEvent<HTMLInputElement>) => void);
    classnames: string;
    placeholder?: any;
}
export interface InputProps extends IProps{
    isvalid?: boolean;
}
interface InputState{
    isvalid: boolean|undefined;
}
export class Input extends Component<InputProps, InputState>{
    iProps: IProps|null = null;
    state: InputState= {
        isvalid: true
    }
    constructor(props: InputProps){
        super(props);
        ({isvalid: this.state.isvalid, ...this.iProps} = this.props);
        this.state.isvalid = this.state.isvalid===undefined ? true: this.props.isvalid;          
    }
    render(){
        return (
                <input className={ this.state.isvalid===true ? this.iProps?.classnames : 'is-invalid' + ' ' + this.props.classnames} {...this.iProps}   />
        )
    }
}

输入是一个子组件。它第一次渲染。在componentDidMountos 父组件中,我正在使用setState. 我验证了父组件的状态已更改,但不知何故render不是由 React 触发的。因此,状态的变化不会反映在子组件中。

请帮助我找出我的代码有什么问题。

标签: javascriptreactjstypescript

解决方案


我得到了这个问题的答案。

我假设每当 React 执行时render,它都会重新创建组件。即我假设重新渲染将触发Input组件的构造函数。最后,我在应用程序中进行了一些调试,发现constructor在重新渲染时不会执行。因此,我没有stateInput.

发现我必须使用名为componentDidUpdatein的生命周期方法Input

 componentDidUpdate(){
        const isvalid = this.props.isvalid===undefined ? true: this.props.isvalid;
        if(this.state.isvalid !== isvalid)
            this.setState({isvalid: isvalid});
    }

我添加了这个,Input问题就解决了。


推荐阅读