Когда использовать реквизиты, а когда состояние в подкомпонентах 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 из флажка будет действовать как состояние. Оно обновляется, когда пользователь нажимает на флажок, и затем новое состояние передается флажку.

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

1 ответ

Решение

Обычно выходом является применение шаблона Stateful parent и childless child.

В вашем случае 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
    }
}

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

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

Другие вопросы по тегам