javascriptreactjstabsreact-tabs

How to render react components in tabs?


Here, how to show only "ListSelected" component in a tab called "Selected Planets" and the rest whole component(FetchPlanets) in a tab called "Planets List" tab. How to render only "ListSelected" component in a different tab and the rest whole component ("FetchPlanets") in a different tab? and so it shouldn't refresh the selected planets passed as props

FetchPlanets.jsx

import React from "react";
import { ListGroup, Container } from "react-bootstrap";
import "./components.css";
import ListSelected from "./ListSelected";
export default class FetchPlanets extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      planets: null,
      selectedPlanets: []
    };
  }
  async componentDidMount() {
    const url = "asdf";
    const res = await fetch(url);
    const data = await res.json();
    this.setState({ planets: data, loading: false });
    console.log(this.state.planets);
  }
  fetch = e => {
    const data = this.state.selectedPlanets;
    data.push(e.target.innerText);
    this.setState({
      selectedPlanets: data
    });
  };

  render() {
    const splanets = this.state.selectedPlanets.map(function(item) {
      return <li> {item} </li>;
    });
    return (
      <Container fluid>
        {this.state.loading || !this.state.planets ? (
          <div>Loading...</div>
        ) : (
          <ListGroup>
            {this.state.planets.map((planetnames, index) => {
              return (
                <ListGroup.Item
                  onClick={e => {
                    this.fetch(e);
                  }}
                  className="selectlg"
                >
                  {planetnames.id}
                </ListGroup.Item>
              );
            })}
          </ListGroup>
        )}

        <ListSelected selp={splanets} />
      </Container>
    );
  }
}

Solution

  • You need to make two different components for listing both planets and selected planets. This is the sandbox link

    This is how the app.js looks like

    import React from "react";
    import "./styles.css";
    import FetchPlanets from "./components/FetchPlanets";
    
    import ListSelected from "./components/ListSelected";
    
    import { Tabs, Tab } from "react-bootstrap";
    import "bootstrap/dist/css/bootstrap.min.css";
    
    export default function App() {
      const [selectedPlanet, setSelectedPlanet] = React.useState([]);
      return (
        <div className="App">
          <Tabs defaultActiveKey="planet" id="uncontrolled-tab-example">
            <Tab eventKey="planet" title="Planets">
              <FetchPlanets updatePlanets={e => setSelectedPlanet([...e])} />
            </Tab>
            <Tab eventKey="list" title="Selected">
              <ListSelected selp={selectedPlanet} />
            </Tab>
          </Tabs>
        </div>
      );
    }
    

    This is how your selected planets component look like

    import { ListGroup } from "react-bootstrap";
    import React from "react";
    function ListSelected({ selp }) {
      return (
        <ListGroup>
          <ListGroup.Item>
            {selp.length > 0 &&
              selp.map((selected, index) => (
                <ListGroup.Item key={index}>{selected}</ListGroup.Item>
              ))}
          </ListGroup.Item>
        </ListGroup>
      );
    }
    
    export default ListSelected;
    

    And finally, this is how your planets listing component looks like

    import React from "react";
    import { ListGroup, Container } from "react-bootstrap";
    import "./components.css";
    export default class FetchPlanets extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          loading: true,
          planets: null,
          selectedPlanets: []
        };
      }
      async componentDidMount() {
        const url = "https://assignment-machstatz.herokuapp.com/planet";
        const res = await fetch(url);
        const data = await res.json();
        this.setState({ planets: data, loading: false });
        console.log(this.state.planets);
      }
      fetch = e => {
        const data = this.state.selectedPlanets;
        if (!data.includes(e.target.innerText)) {
          data.push(e.target.innerText);
          this.setState(
            {
              selectedPlanets: data
            },
            () => {
              this.props.updatePlanets(this.state.selectedPlanets);
            }
          );
        }
      };
    
      render() {
        return (
          <Container fluid>
            {this.state.loading || !this.state.planets ? (
              <div>Loading...</div>
            ) : (
              <ListGroup>
                {this.state.planets.map((planetnames, index) => {
                  return (
                    <ListGroup.Item
                      key={index}
                      onClick={e => {
                        this.fetch(e);
                      }}
                      className="selectlg"
                    >
                      {planetnames.id}
                    </ListGroup.Item>
                  );
                })}
              </ListGroup>
            )}
          </Container>
        );
      }
    }