简体   繁体   中英

ReactJS Custom Hook not rendering the expected output

I am experimenting with ReactJS custom Hooks, but I don't understand what's happening in the example below!

I expect to see on the screen: 'Label: <followed by one of the selected option ("Bananas" or "Apples" or "Oranges")>', but it is 'Label: ' so the optionis undefined!

Could someone explain me what's happening under the hood, why I cannot see the expected output for the option?

const useFruit = () => {
  const [option, setOption] = useState<string>();
  const [options] = useState(["Bananas", "Apples", "Oranges"]);

  return {
    option,
    setOption,
    options,
  };
};

const FruitDropdown = () => {
  const { options, setOption } = useFruit();

  return (
    <select
      placeholder="Select option"
      onChange={(e) => {
        setOption(e.target.value);
      }}
    >
      {options.map((option) => (
        <option value={option}>{option}</option>
      ))}
    </select>
  );
};


const FruitLabel = () => {
  const { option } = useFruit();
  return (
    <label>Label: {option}</label>
  );
};

export default function play() {
  return (
    <>
      <FruitDropdown />
      <FruitLabel />
    </>
  );
}

Just because they are using the same custom hook, they are not automatically sharing state. Every time you run useFruits you will create a new isolated state which is only accessable in that instance how the hook. And whenever a the state is created it defaults to undefined.

What you need in order to solve your problem is to wrap your components inside a context and place the state inside the context. Something like this:

const FruitContext = createContext()

const FruitProvider = ({ children }) => {
    const [option, setOption] = useState<string>();
  const [options] = useState(["Bananas", "Apples", "Oranges"]);

   return (
       <FruitContext.Provider value={{ option, setOption, options }}>{children}</FruitContext.Provider>
   )
}

export const useFruits = () => useContext(FruitContext)

Dont forget to wrap your components:

<FruitProvider>
      <FruitDropdown />
      <FruitLabel />
</FruitProvider>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM