Реагировать - состояние обновления на реквизитах изменено - элемент ввода - PullRequest
1 голос
/ 09 апреля 2019

Я уже прочитал все вопросы о переполнении стека, связанные с этой проблемой, а также это официальное сообщение о реакции и предпочтительные решения.
Больше не рекомендуется использовать componentWillReceiveProps!

Прежде чем пометить этот вопрос как дубликат, пожалуйста, поймите мой конкретный вопрос, я не нашел никакого решения для моей конкретной проблемы.

То, что я пытаюсь сделать, очень просто:
У меня есть компонент KInputRange, который получил значение из реквизита и отправить значение (событие обратного вызова) на событие onEnter (отправит значение для сервера только при вводе) Значение props.value может случайно меняться (поступая через веб-сокет с сервера)

Мой вопрос :
Внутри моих компонентов атрибут значения <input> будет получать данные от props или от state?

Если из реквизита: Как я могу обновить значение внутри, когда пользователь вводит данные?

Если из состояния: Как я могу обновить новое значение, если props.value случайно изменился с сервера?

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

Это мой код:

class KInputRange extends React.Component<any, any> {
    constructor(props: any) {
        super(props);
    }

    private onKeyDown(e: any): void {
        //If the key is enter call to props.onEnter with the current value

    }

    private onChange(e: any): void {
        //if user change the value- change the internal value
    }

    public render() {
        return (
            <input value={?????} type="text" onChange={(e) => this.onChange(e)} onKeyDown={(e) => this.onKeyDown(e)}/>
        );
    }
}

Использование:

   <KInputRange value={this.state.dataFromTheServer}   onEnter={(val: number) => this.kInputRangeEnterClicked(val)}/>

Ответы [ 3 ]

1 голос
/ 16 апреля 2019

Во-первых, как сказал @Atul, вам действительно нужно использовать getDerivedStateFromProps.Это все потому, что вам нужно контролировать значение вашего компонента в зависимости от - реквизита и внутреннего состояния.Предполагая, что вы используете поток, этот код должен помочь:

// @flow
import * as React from "react";

type Properties = {
    remoteValue: string,
    onSubmit: (value: string) => void
};

type State = {
    remoteValueMemo: string,
    internalValue: string
};

class KInputRange extends React.Component<Properties, State> {

    static defaultProps = {
        remoteValue: "",
        onSubmit: () => {}
    };

    state = {
        remoteValueMemo: this.props.remoteValue,
        internalValue: this.props.remoteValue
    };

    static getDerivedStateFromProps(props: Properties, state: State) {
        if (state.remoteValueMemo !== props.remoteValue) {
            return {
                remoteValueMemo: props.remoteValue,
                internalValue: props.remoteValue};
        }
        return null;
    }

    handleValueChange = (event: SyntheticEvent<HTMLInputElement>) => {
        this.setState({internalValue: event.currentTarget.value});
    };

    handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
        if (event.keyCode === 13) {
            this.props.onSubmit(this.state.internalValue);
        }
    };

    render(): React.Node {
        const {internalValue} = this.state;

        return (
            <input value={internalValue} onChange={this.handleValueChange} onKeyDown={this.handleKeyDown}/>
        );
    }
}

export default KInputRange;
1 голос
/ 10 апреля 2019

Вы можете использовать компонент функции , как упомянуто в сообщении, которое вы связали здесь.Для внутреннего обновления значения вы можете использовать React's State Hook .

Примерно так:

import React, { useState } from 'react';

const KInputRange = (props) => {

    const [value, setValue] = useState(props.value);

    function onKeyDown(e: any): void {
        //If the key is enter call to props.onEnter with the current value
    }

    function onChange(e: any): void {
        setValue(e.target.value);
    }

    return (
            <input value={value} type="text" onChange={(e) => this.onChange(e)} onKeyDown={(e) => this.onKeyDown(e)}/>
    );
}
0 голосов
/ 16 апреля 2019

Вы можете использовать useEffect ловушку реагирования, когда вам нужно что-то сделать для изменения определенного реквизита в компоненте функции

useEffect(() => {
    // You can place your logic here to run whenever value changes 
},[value]);

[значение] является зависимостью, так что при каждом изменении значения, которое вы используетеEffect, вызывает

Надеюсь, что это полезно для вас.

...