AviatingFotographer
AviatingFotographer

Reputation: 328

Instances of React Component

I have this app component:

function App() {
  const [ active, setActive ] = useState('student')
  const [ row, setRow ] = useState(true)
  const [ currentComponent, setCurrentComponent ] = useState(<Table setRow={setRow} represent="students" />)
  const [ contextData, setContextData ] = useState({});

  useEffect(() => {
    switch (active) {
      case 'student':
        setCurrentComponent(<Table setRow={setRow} represent="students" />)
        return
      case 'employee':
        setCurrentComponent(<Table setRow={setRow} represent="employees" />)
        return
      case 'class':
        setCurrentComponent(<div>class</div>)
        return
    }
  }, [ active ])

  return (
    <appContext.Provider value={{ contextData, setContextData }} >
        <div className="App">
          { row ? <TabRow setActive={setActive} active={active} /> : "" }
          { currentComponent }
        </div>
    </appContext.Provider>
  );
}

I just realized that the Table component does not mount and unmount between 'student' as active and 'employee' as active. Does this mean that the component only re renders since props change?

Upvotes: 1

Views: 211

Answers (1)

Ross Allen
Ross Allen

Reputation: 44900

Rendered components should not be stored in state, that will lead to unexpected behavior in React. Make sure all components render all the time and only store non-components in state:

function App() {
  const [ active, setActive ] = useState('student')
  const [ row, setRow ] = useState(true)
  const [ contextData, setContextData ] = useState({});

  let currentComponent;
  switch (active) {
    case 'employee':
      currentComponent = <Table setRow={setRow} represent="employees" />
      return
    case 'class':
      currentComponent = <div>class</div>
      return
    case 'student':
    default:
      currentComponent = <Table setRow={setRow} represent="students" />
      return
  }

  return (
    <appContext.Provider value={{ contextData, setContextData }} >
        <div className="App">
          { row ? <TabRow setActive={setActive} active={active} /> : "" }
          { currentComponent }
        </div>
    </appContext.Provider>
  );
}

Upvotes: 1

Related Questions