Reputation: 57
I'm working on a project that has to do with playlist, so what I want to execute is whenever one of the songs on the playlist is clicked the image that is attached to the song should be viewed. So, I have my code this way...
const Component = () => {
const value = useContext(DataContext);
const [data, setData] = useState(null);
const [currentData, setCurrentData] = useState(null);
useEffect(() => {
const url =
"https://52-90-82-235.maverickmaven.com/geotourdata/json.cfm?h=-107,37,s,en,3A771765";
const currentValue = value;
axios({
method: "get",
url,
responseType: "stream",
}).then((response) => {
let features = response.data.features.filter((elem) => {
return elem.type === "Feature";
});
setData(features);
const currentDatafile = data?.filter((data) => {
return data?.assets[0].audio === value;
});
setCurrentData(currentDatafile);
});
}, [setCurrentData]);
};
So, what this code does is that it returns the array that has the picture, but the problem is that it only filters once and repeatedly returns the same value even if I click on another song, and I need it to filter every time I clicked on the songs(i.e the function is executed).
I tried filtering and mapping at the same time, but it didn't work. or maybe I didn't write the syntax well enough.
Please I need help.
Upvotes: 0
Views: 1185
Reputation: 30
Move these lines to new useEffect hook. Will trigger after you set data
useEffect(() => {
const currentDatafile = data?.filter((item) => {
return item.assets[0].audio === value;
});
setCurrentData(currentDatafile)},[data])
Upvotes: 1
Reputation: 169051
You shouldn't re-fetch the data from the remote source every time. I've wrapped that in a custom hook instead, here (and a custom fetcher function to make testing/mocking easier).
Then, you shouldn't hold the selected object in the state unless you need to modify it internally (in which case you should copy it into a state atom anyway); instead, just hold the ID.
function fetchTourData() {
return fetch('https://52-90-82-235.maverickmaven.com/geotourdata/json.cfm?h=-107,37,s,en,3A771765')
.then(response => response.json())
.then(data => data.features.filter((elem) => elem.type === 'Feature'));
}
function useTourData() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetchTourData().then(setData);
}, [setData]);
return data;
}
const Component = () => {
const tourData = useTourData();
const [selectedId, setSelectedId] = React.useState(null);
const selectedTour = (tourData || []).find(t => t.id === selectedId);
if (tourData === null) {
return <div>Loading</div>
}
return (
<div>
<div>
Selected: {JSON.stringify(selectedTour || "nothing")}
</div>
<ul>
{tourData.map(t => <li key={t.id}><a href="#" onClick={() => setSelectedId(t.id)}>{t.name}</a></li>)}
</ul>
</div>
);
};
ReactDOM.render(<Component />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1