реагировать состояние асинхронно в рендере - PullRequest
0 голосов
/ 14 февраля 2019

У меня небольшие асинхронные проблемы с методом рендеринга.

Я инициирую переменную состояния textInRenameTodoPopOverInput с помощью переменной props.

Проблема заключается в том, что при изменении переменной props изменяется состояниепеременная всегда остается на изначально заданном значении (для этого примера это будет 'dummyText'), поэтому при изменении значения моего реквизита this.props.todoToRename.text консоль всегда возвращает:

>> Props in Modal {this.props.todoToRename.text} // Here the props has the expected new value
>> State in modal dummyText // But the state is not refresh and keep 'dummyText'

вот мой кодчто я упростил:

import React from "react";

export default class RenameTodoPopOver extends React.Component {

    constructor(props) {

        super(props);

        this.handleChange = this.handleChange.bind(this);

        this.state = {
            textInRenameTodoPopOverInput: this.props.todoToRename.text,
        }


    }

    handleChange = (event) => {
        this.setState({ textInRenameTodoPopOverInput: event.target.value });
    }

    render() {

        console.log('Props in Modal ' + this.props.todoToRename.text);
        console.log('State in modal ' + this.state.textInRenameTodoPopOverInput);

        return (
            <input type="text" defaultValue={this.state.textInRenameTodoPopOverInput} onChange={this.handleChange} />
        );
    }
}

У вас есть идеи, в чем заключается моя ошибка или как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

некоторые проблемы с вашим кодом: 1. вы используете реквизит и назначаете его в плохое состояние.2. вы можете переместить «состояние» в родительский компонент и позволить родительскому компоненту отправлять функцию text и handle как props

    //in the parent component
import React from "react";

export default class ParentRenameTodoPopOver extends React.Component {

    constructor(props) {

        super(props);

        this.handleChange = this.handleChange.bind(this);

        this.state = {
            textInRenameTodoPopOverInput: this.props.todoToRename.text,
        }


    }

    handleChange = (event) => {
        this.setState({ textInRenameTodoPopOverInput: event.target.value });
    }

        render() {
            return (
                <RenameTodoPopOver 
                textInRenameTodoPopOverInput= 
 {this.state.textInRenameTodoPopOverInput}
                handleChange = {this.handleChange}
    />
            );
        }
    }

export default ParentRenameTodoPopOver

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

//in the child component
import React from "react";

const RenameTodoPopOver = (props)=>
        return (
            <input 
             type="text" 
             defaultValue={props.textInRenameTodoPopOverInput} 
             onChange={props.handleChange} />
        )
}
export default RenameTodoPopOver;

при разработке компонентов в реагировать легче написать, если разделить компоненты на чисто функциональные и чисто презентационные компоненты.Здесь родительский компонент является чисто функциональным, т. Е. Он имеет всю логику, с другой стороны, дочерний компонент является чисто функциональным, он не имеет логики и получает все функции и состояние, передаваемые ему от родителя посредством реквизита.

0 голосов
/ 14 февраля 2019

Вы должны использовать getDerivedStateFromProps, чтобы обновить операционные параметры на основе состояния компонента.

export default class RenameTodoPopOver extends React.Component {
    state = { textInRenameTodoPopOverInput: '' }

    static getDerivedStateFromProps(nextProps){
      if(nextProps.todoToRename.text){
        return {
          textInRenameTodoPopOverInput: nextProps.todoToRename.text
        }
      }
    }

    handleChange = (event) => {
        this.setState({ textInRenameTodoPopOverInput: event.target.value });
    }

    render() {
        console.log('Props in Modal ' + this.props.todoToRename.text);
        console.log('State in modal ' + this.state.textInRenameTodoPopOverInput);

        return (
            <input type="text" defaultValue={this.state.textInRenameTodoPopOverInput} onChange={this.handleChange} />
        );
    }
}
...