0

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>
    );
  }
}
ROOT
  • 11,363
  • 5
  • 30
  • 45
jeevan kotian
  • 137
  • 2
  • 12

2 Answers2

1

You can use this example to separate your content into tabs: react-tabs

Here is the code :

import React, { Component } from 'react';
import { render } from 'react-dom';
import Tabs from "./Tabs";
import Tab from "./Tab";
import './style.css';

class App extends Component {

  render() {
    return (
      <Tabs>
        <Tab value="banana" header="Banana Header">
          Banana
        </Tab>
        <Tab value="apple" header="Apple Header">
          Apple
        </Tab>
      </Tabs>
    );
  }
}

render(<App />, document.getElementById('root'));

There is also this npm package that seems to fit your needs. It'll be eaier to use, have a look:

import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';

export default () => (
  <Tabs>
    <TabList>
      <Tab>Title 1</Tab>
      <Tab>Title 2</Tab>
    </TabList>

    <TabPanel>
      <h2>Any content 1</h2>
    </TabPanel>
    <TabPanel>
      <h2>Any content 2</h2>
    </TabPanel>
  </Tabs>
);

[Edit]: I think i finally got what you wanted to do. So you need to get your selected planets in your parent to be able to pass it as prps to your SelectedList component. You jsut have to set your list in your parent state, as follow :

import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";

const App = () => {
  const [selectedPlanets, setSelectedPlanets] = React.useState([]);

  return (
    <div>
      <div className="tab-1">
        <FetchPlanets setSelectedPlanets={setSelectedPlanets} />
      </div>
      <div className="tab-2">

        <SelectedPlanets planets={selectedPlanets} />
        </div>
    </div>
  );
};

const FetchPlanets = ({ setSelectedPlanets }) => {
  const planets = ["Mars", "Uranus", "Earth", "Jupiter"];

  React.useEffect(() => {
    const selectedPlanets = [];
    planets.forEach(p => {
      if (p === "Mars" || p === "Jupiter") selectedPlanets.push(p); // Arbitrarily selected planets for the example
    });

    setSelectedPlanets(selectedPlanets);
  }, []);

  return (
    <div>
      {planets.map(p => (
      <span>{p} </span>
    ))}
    </div>
  );
};

const SelectedPlanets = ({ planets }) => (

  <div>
    {planets.map(p => (
      <span>{p} </span>
    ))}
  </div>
);

render(<App />, document.getElementById("root"));

Here is the repro on stackblitz

Quentin Grisel
  • 4,794
  • 1
  • 10
  • 15
1

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>
    );
  }
}
Akhil Aravind
  • 5,741
  • 16
  • 35