1

我已经阅读了与这个问题相关的所有堆栈溢出问题,还有这个官方反应帖子和首选解决方案。
不建议再使用componentWillReceiveProps了!

在将此问题标记为重复之前,请理解我的具体问题,我没有看到针对我的具体问题的任何解决方案。

我想做的很简单:
我有组件KInputRange从道具接收值并将值发送出去(回调)onEnter事件(仅在输入时将值发送到服务器)props.value可以随机更改(即将到来通过来自服务器的 websocket)

我的问题
在我的组件中,<input>value 属性将从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)}/>
4

4 回答 4

1

首先,正如@Atul 所说,您确实需要使用 getDerivedStateFromProps。这完全是因为您需要根据道具和内部状态来控制组件值。假设您使用 flow 此代码应该会有所帮助:

// @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;
于 2019-04-16T06:24:37.963 回答
1

传递给 useState 的参数不用于更新重新渲染时的状态。

您应该使用useEffect Hook。

import React, { useEffect, useState } from 'react';

const Test = (props) => {

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

    useEffect(() => {
        setValue(props.value);
    }, [props.value])
  
    //...
}

类似的主题:React.useState does not reload state from props

于 2020-11-25T13:49:03.263 回答
1

您可以使用您在此处链接的帖子中提到的功能组件。要在内部更新值,您可以使用React 的 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)}/>
    );
}
于 2019-04-10T06:23:04.200 回答
-2

useEffect每当您需要对功能组件中的特定道具更改做某事时,您都可以使用反应钩子

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

[value] 是一个依赖项,因此每当值更改时,您 useEffect 挂钩调用

以上希望对你有所帮助。

于 2019-04-16T06:40:26.307 回答