如何在React Hooks中将道具更改为状态?

时间:2019-01-10 14:36:12

标签: reactjs react-hooks

在简单的反应类组件中,我们用来将道具更改为这种方式:

constructor(props) {
    super(props)

    this.state = {
      pitch: props.booking.pitch,
      email: props.booking.email,
      firstName: props.booking.firstName,
      arrivalDate: props.booking.arrivalDate
    }
} 

但是我不知道如何在新功能(如Hooks)中做到这一点,但我正在尝试以这种方式做到这一点。

const GenerateDescHook = ({ description: initialDesc }) => {
  const [description, setDescription] = useState(null)

useEffect(() => {
    setDescription(initialDesc)
  }, {})

 function handleChangeVariance(newVariance) {
    setDescription({
      ...description,
      template: {
        ...description.template,
        variance_name: newVariance,
      },
    })
  }

}

基本上,我只需要更改描述道具,该道具来自另一个父组件以变为状态。请问您能告诉我如何以新的方式使用Hooks吗?

4 个答案:

答案 0 :(得分:9)

您可以像这样将初始状态作为第一个参数传递给useState

const GenerateDescHook = ({ description: initialDesc }) => {
  const [description, setDescription] = useState(initialDesc)

  ...

答案 1 :(得分:7)

问题出在{};

每次initialDesc更改时,您都应该这样做以使状态与描述同步:

useEffect(() => {
    setDescription(initialDesc)
  }, [initialDesc]); // Only rerun if initialDesc changes

请参阅:React docs: Tip: Optimizing Performance by Skipping Effects

答案 2 :(得分:1)

您的状态的初始值是传递给useState的状态:

const GenerateDescHook = ({ description: initialDesc }) => {
  const [description, setDescription] = useState(initialDesc)

documentation指出:

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

等同于:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

答案 3 :(得分:0)

很难达到依赖道具价值的状态,同时还要避免不必要的重新渲染。

这是我创建此类钩子的尝试:

/**
 * Replacement for useState which depends on prop value and avoids unnecessary re-renders.
 */
export function useStateBasedOnProps(propValue) {
    const [, update] = useState(false);

    const [state, setState] = useMemo(() => {
        const state = {};
        return [
            state,
            (value) => {
                if (value instanceof Function) {
                    state.value = value(state.value);
                } else {
                    state.value = value;
                }
                update((tick) => !tick);
            }
        ];
    }, [update]);

    if (state.prevPropValue !== propValue) {
        state.prevPropValue = propValue;
        state.value = propValue;
    }

    return [state.value, setState];
}

这是一个用法示例:

function IncButton({initialValue}) {
    const [value, setValue] = useStateBasedOnProps(initialValue);
    const increment = useCallback(() => setValue((prev) => prev + 1), [setValue]);
    return <button onClick={increment}>Click to increment: {value}</button>;
}

完整示例:https://gist.github.com/mdevils/b861610780300784292194f65886517a

相关问题