реакция не перерисовывается при обновлении реквизита

вот мой render метод FormEl компонента.

return <div>
            <button type="button" onClick={this.clicked}>click to add 1 input</button>
            <Inputs count={this.state.childcount}/>
        </div>

в методе clicked я обновляю childcount на 1, используя setState

это класс Inputs

class Inputs extends React.Component {
    constructor(props) {
        super(props);
        console.log("Input constructor is running.");
        this.state = {value: '', p: "p", count: props.count};
    }

    render() {
        let c = [];
        for (let i = 0; i < this.state.count; i++) {
            c.push(
                <div key={"id-" + (i * 10)}>
                    <input type="text" defaultValue={this.state.value}/>
                    <p> {this.state.p}</p>
                </div>);
        }
        return <div>
            {c}
        </div>;
    }
}

Но когда я обновляю childcount в clicked, я вижу, что FormEl перерисовывается, count в <Inputs.. соответственно увеличивается. Но он не вызывает constructor из Inputs, кроме как в первый раз (загрузка страницы).


person bula    schedule 06.09.2018    source источник
comment
Имеет смысл для меня. Вызов setState() обновит компонент, т.е. будет вызван render(). Это не означает, что весь компонент будет заново создан, т.е. вызов constructor   -  person Anand Undavia    schedule 06.09.2018
comment
Дублирование этого вопроса: stackoverflow.com/a/29074980/2404452   -  person blaz    schedule 06.09.2018
comment
Вам нужно использовать componentWillReceiveProps()   -  person Abin Thaha    schedule 06.09.2018
comment
@Abinthaha componentWillReceiveProps() скоро станет устаревшим. Таким образом, не рекомендуется использовать это. Вместо этого он должен использовать componentDidUpdate()   -  person vicke4    schedule 06.09.2018
comment
Ага. Он будет объявлен устаревшим в ближайшее время. Но если вы работаете над версией реакции меньше 16, вы можете использовать ее тогда   -  person Abin Thaha    schedule 06.09.2018
comment
почему голосование против?   -  person bula    schedule 06.09.2018


Ответы (3)


Вместо этого напрямую используйте this.props.count.

for (let i = 0; i < this.props.count; i++) {
person Amruth L S    schedule 06.09.2018

Здесь метод конструктора компонента Inputs будет вызываться только один раз после его монтирования. Его больше никогда не позовут. Итак, что вы можете сделать, так это иметь метод componentDidUpdate в компоненте Inputs и setState, когда входящая опора count отличается от вашего текущего состояния.

Или же вы можете напрямую использовать this.props.count в for, как это было предложено @lsa4299.

person vicke4    schedule 06.09.2018

конструктор предназначен для вызова только один раз, поэтому вы можете установить только там начальное состояние.

Фактически, поскольку вы не изменяете состояние из класса Inputs, вам вообще не нужно какое-либо состояние. Вы можете объявить const value=""; константа п = "р"; в верхней части вашего метода рендеринга. И просто используйте this.props.count вместо this.state.count

В этом случае вы можете удалить конструктор.

Если вы позже измените поведение своего компонента и вам нужно установить состояние в зависимости от новых реквизитов (не текущего случая), вы можете проверить метод getDerivedStateFromProps.

person Carlos Ruana    schedule 06.09.2018