Когда использовать Props и когда State в субкомпонентах Preact

Я изучаю preact, но это может касаться и React.

Скажем, у меня есть список флажков, каждый из которых содержит дополнительный HTML, например этот (Typescript):

export class MyCheckbox extends Component<Props, State> {

    render(props, state) {
        return (
            <div>
                <input
                    type="checkbox"
                    checked={state.checked}
                    onChange={props.onUpdate}
                    />
                <div>
                    {props.name}
                    <!-- other GUI elements -->
                </div>
            </div>
        );
    }
}

Затем эти компоненты используются в компоненте более высокого уровня, например:

render(props, state) {

    return (
        <div class={style.finding}>
            <form>
                { this.elements
                    .map(el => (
                        <MyCheckbox name={el.name} checked={el.checked} onUpdate={this.onUpdate()} />
                    ))
                }
            </form>
        </div>        
    </div>
);

Как видите, компонент более высокого уровня сообщает флажку, следует ли его ставить или нет. Таким образом, объект Props флажка имеет свойство checked, которое определяет, следует ли устанавливать флажок, когда он становится видимым.

Однако нам также нужно свойство checked на State, потому что пользователь может щелкнуть флажок и, таким образом, обновить его. Итак, Props.checked означает «изначально проверено», а State.checked означает «проверено в настоящее время».

Но если пользователь установит флажок, метод onUpdate обновит модель this.elements на компоненте более высокого уровня. Это вызовет render() на компоненте более высокого уровня, который, в свою очередь, передаст новый Props.checked флажку.

Это означает, что Props флажка будет действовать как состояние. Он обновляется, когда пользователь щелкает флажок, а затем новое состояние передается флажку.

Это нормально? Или мой дизайн как-то не так? Нужно ли вообще дочернему компоненту состояние?


person Bass    schedule 21.08.2018    source источник


Ответы (1)


Обычно можно применить шаблон Родительский объект с отслеживанием состояния и дочерний элемент без состояния.

В вашем случае MyCheckbox должен быть без состояния (не должен содержать переменную состояния checked), а отмеченное значение должно быть свойством.

Состояние проверенного значения должно обрабатываться родительским состоянием.

export class MyCheckbox extends Component<Props, State> {
    render(props, state) {
        return (
            <div>
                <input
                    type="checkbox"
                    checked={props.checked}
                    onChange={props.onUpdate} />
                <div>
                    {props.name}
                    <!-- other GUI elements -->
                </div>
            </div>
        );
    }
}

родитель:

export class Parent extends Component<Props, State> {
    ...
    render(props, state) {
        return (
            <div class={style.finding}>
                <form>
                    { this.elements
                        .map(el => (
                            <MyCheckbox name={el.name} checked={this.isChecked(el)} onUpdate={this.onUpdate()} />
                        ))
                    }
                </form>
            </div>        
        </div>
    );

    isChecked(elem) {
        // use this.state to verify to return a boolean representing the checkbox checked state
    }
}

Всегда хорошо делать компонент без состояния. Немного уродливо иметь свойство и значение состояния, которые представляют один и тот же аспект компонента.

Надеюсь это поможет

person Martín Zaragoza    schedule 21.08.2018