How should I render multi-state component, which fetches API?

Viewed 71

I am using React with Node.js.

I have a component ItemList, which fetches some API in the componentDidMount() method, because it allows me to easily render a "loading state".

I need to pass a state to this component, which would change the API's url using a toggle button. This toggle button is an individual component (ToggleButton). These two components are siblings and I am using parent as a way for these components to communicate.

I thought Context is perfect for this kind of job. The issue is, that using React's Context is just re-rendering (calling the function render() of a ItemList and not remounting the component, thus not calling the componentDidMount() method or even constructing the component again).

export const ToggleContext = React.createContext({
    switched: false
});
export default class Items extends React.Component
{
    constructor(props)
    {
        super(props)
        
        this.state = {
            switched: false
        }

        this.toggleSwitch = () => {
            this.setState(state => ({
                switched: !state.switched
            }))
        }
    }

    render()
    {
        console.log(this.state.switched)
        return (
            <>
                <div class="page-header">
                    <div class="container-fluid">
                        <h2 class="h5 mb-0">Items</h2>
                    </div>
                </div>
                <section class="py-0">
                    <div class="container-fluid">
                        <ToggleContext.Provider value={this.state.switched}>
                            <ToggleButton callFunc={this.toggleSwitch}/>
                            <ItemList loadWeb={this.state.switched}/>
                        </ToggleContext.Provider>
                    </div>
                </section>
            </>
        )
    }
}

ItemList component is heavily inspirated by React docs

I am succesfully getting the changed state through ToggleButton in parent component, sending it to ItemList and picking it up as props.loadWeb, I am just not sure if my implementation is wrong or even if what I demand is possible with Context.

Is it possible to reconstruct the whole component using context, should I use refs, sould I fetch the API in the render() method, etc.?

2 Answers

What you are doing seems right, I would say, you could probably simplify (in my opinion) by using function components along with hooks.

import React, {useState} from 'react';

const Items = () => {
  const [toggled, toggle] = useState(false);

  return (
    <div class="container-fluid">
      <div class="page-header">
        <h2 class="h5 mb-0">Items</h2>
      </div>

      <section class="py-0">
        <ToggleButton callFunc={toggle(!toggled)}/>
        <ItemList loadWeb={toggled}/>
      </section>
    </div>
  );
};
Related