简体   繁体   中英

What is the difference '<Toolbar />' and '{ Toolbar() }' in react render?

I found useContext(ThemeContext)'s value is not update when use '{ Toolbar() }' in render.

What is the difference '' and '{ Toolbar() }' in react render or diff?

import React, { useContext, useState } from "react";
import "./styles.css";

const themes = {
  light: {
    name: "light",
    foreground: "black",
    background: "white"
  },
  dark: {
    name: "dark",
    foreground: "white",
    background: "black"
  }
};

const ThemeContext = React.createContext(null);

const Toolbar = props => {
  const theme = useContext(ThemeContext) || {};
  console.log(`Toolbar theme`, theme);
  return (
    <div
      style={{
        height: 60,
        backgroundColor: theme.background,
        color: theme.foreground
      }}
    >
      <div>{theme.name}</div>
    </div>
  );
};

export default function App() {
  const [currentTheme, setCurrentTheme] = useState(themes.light);

  const toggleTheme = theme => {
    setCurrentTheme(theme);
  };

  console.log(`currentTheme`, currentTheme);

  return (
    <div className="App">
      <ThemeContext.Provider value={currentTheme}>
        <div>
          <button onClick={() => toggleTheme(themes.light)}>light</button>
          <button onClick={() => toggleTheme(themes.dark)}>dark</button>
        </div>
        {/* Toolbar() */}
        {/* {Toolbar()} */}
        <Toolbar />
      </ThemeContext.Provider>
    </div>
  );
}

If you call it as a function ( ToolBar() ), it essentially returns its content, and is not considered a React component as such. If you use <Toolbar /> , it is a component, and the right way to use it.

In short, calling it as a function is like saying "Print here whatever this function returns", where as using it as <Toolbar / is like saying "Render this component here".

The function call will cause the states, context, or effects to fail, so your useContext call would not have the intended effect if you do not use the component as a component.

Even if a component is a functional component, it should not be used directly as a function.

React contains a lot of magic to have useContext and friends to work, but it cannot do so when the component is not used as a component. If you're interested in learning more about the mechanisms behind React, and why useContext would not work, check this article .

In ReactJS you call component like this:

<Component />

and you call function like this:

{nameOfFunction()}

if you have any constant for example you print its value:

const[value, setValue] = useState("Some Text...");

...

{value} // would pring Some Text...

<Toolbar /> generates (through JSX ) [1] [2] :

React.createElement(Toolbar, null)

While Toolbar() is a function call.

Don't call function components. Render them.

This is why you need to use JSX (or React.createElement) when rendering components rather than simply calling the function. That way, any hooks that are used can be registered with the instance of the component that React creates.

In your example, useContext won't register to the component's instance on calling Toolbar() as referenced from the blog post.

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