How to change props to state in React Hooks?

前端 未结 4 1657
温柔的废话
温柔的废话 2021-02-02 07:41

In Simple react class component we used to change the props to state this way:

constructor(props) {
    super(props)

    this.state = {
      pitch: props.book         


        
相关标签:
4条回答
  • 2021-02-02 08:15

    The initial value of your state is the one passed into useState :

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

    As the documentation states :

    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>
      );
    }
    

    Is the equivalent of :

    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>
        );
      }
    }
    
    0 讨论(0)
  • 2021-02-02 08:17

    You can pass your initial state as first argument to useState like this:

    const GenerateDescHook = ({ description: initialDesc }) => {
      const [description, setDescription] = useState(initialDesc)
    
      ...
    
    0 讨论(0)
  • 2021-02-02 08:20

    The problem in your code is with {}. UseEffect hook expects and array, not an object. Use [initialDesc] instead.

    This is how you reset component state when props change

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

    This is how you initialize component state to prop value on first render only

    const GenerateDescHook = ({ description: initialDesc }) => {
      const [description, setDescription] = useState(initialDesc);
    }
    
    0 讨论(0)
  • 2021-02-02 08:32

    It is difficult to achieve a state which depends on prop value and at the same avoid unnecessary re-renders.

    Here is my attempt in creating such a hook:

    /**
     * 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];
    }
    

    Here is a usage example:

    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>;
    }
    

    Full example: https://gist.github.com/mdevils/b861610780300784292194f65886517a

    0 讨论(0)
提交回复
热议问题