简体   繁体   中英

indexing between states in react

Im trying to create an event listener which gives data to the children component.

I have two states

[data,setData]=useState([])
[playData,setPlayData]= useState([])

I get data from an API using fetch and UseEffect with [] parameter to use it only when the app launches

fetch(API_URL)
.then(res=>res.json)
.then(data=>setData(data))

in the APP component I have a children component that receives the playData and an event listener function

<Children data={playData} click={getDataOnClick} />

now i want this event listenener to send data from data as prop one by one as it is clicked,like next next,next.. until data is exhausted

so what I do is define

const box = data

and use

function getDataOnClick (event){
setPlaydata(prevdata=>{
return [...prevdata,box[prevdata.length+1]]
}}

I get an error: box is not iterable or similar when I try braning it out with other array methods. I see that array methods donot work while iterating over states i guess?? how do i solve this?? Is there a hook that i am missing here? Also Slice doest work with state and onjects that I have made equal to the state

You just have to use prevdata.length instead of prevdata.length + 1 or else you will be skipping one element. And you can check if playData has all the elements that are in data before pushing more.

I created a sandbox that does what you're trying to do.

编辑confidence-glade-9x6e1

function Child({ onNext, playData }) {
  return (
    <div>
      <p>{playData}</p>
      <button onClick={onNext}>Next</button>
    </div>
  );
}

export default function App() {
  const [data, setData] = useState([]);
  const [playData, setPlayData] = useState([]);

  useEffect(() => {
    const fakePromise = Promise.resolve(
      Array(50)
        .fill()
        .map((_, i) => i)
    );
    (async () => {
      setData(await fakePromise);
    })();
  }, []);

  const onNext = () => {
    setPlayData((prev) =>
      data.length === prev.length ? prev : [...prev, data[prev.length]]
    );
  };

  return (
    <div className="App">
      <Child playData={playData} onNext={onNext} />
    </div>
  );
}

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