I am having an issue returning a component depending on a value. So firstly I have created state called activeIndex defaulted to 1, I then have 3 buttons that when clicked will change this state to either 1, 2 or 3 this works fine. Then the buttons also run a function called showTab() this checks the value of activeIndex and depending on what value that is equal to will return a different component. I then render this by putting { showTab } but when clicking the different buttons it does not show the different components.
const Forcast = () => {
// Create state to change tabs and return an index
const [activeIndex, setActiveIndex] = useState(1);
const handleClick = (index) => setActiveIndex(index);
const checkActive = (index, className) =>
activeIndex === index ? className : "";
// Create function to return a component depending on activeIndex value
const showTab = (activeIndex) => {
if (activeIndex === 1) {
return <Today />
} else if (activeIndex === 2) {
return <Tomorrow />
} else {
return <SevenDays />
}
}
return (
<div>
<div className="tabs">
<button
className={`tab ${checkActive(1, "active")}`}
onClick={() => {handleClick(1); showTab();}}
>
Product Info
</button>
<button
className={`tab ${checkActive(2, "active")}`}
onClick={() => {handleClick(2); showTab();}}
>
Customer Reviews
</button>
<button
className={`tab ${checkActive(3, "active")}`}
onClick={() => {handleClick(3); showTab();}}
>
Delivery & Returns
</button>
{
showTab
}
</div>
</div>
);
};
I am receiving this error which is telling me that it happens when I return a Component instead of from render.
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
CodePudding user response:
You are rendering showTab
which is a function without calling it.
You can either convert it to a variable or call the function.
Also you don't need to call showTab
on click when you are already handling the state with activeIndex
.
Try this:
export const Forcast = () => {
// Create state to change tabs and return an index
const [activeIndex, setActiveIndex] = useState(1)
const checkActive = (index, className) =>
activeIndex === index ? className : ''
// Create function to return a component depending on activeIndex value
const activeTab = useMemo(() => {
if (activeIndex === 1) {
return <Today />
} else if (activeIndex === 2) {
return <Tomorrow />
} else {
return <SevenDays />
}
}, [activeIndex])
return (
<div>
<div className="tabs">
<button
className={`tab ${checkActive(1, 'active')}`}
onClick={() => setActiveIndex(1)}
>
Product Info
</button>
<button
className={`tab ${checkActive(2, 'active')}`}
onClick={() => setActiveIndex(2)}
>
Customer Reviews
</button>
<button
className={`tab ${checkActive(3, 'active')}`}
onClick={() => setActiveIndex(3)}
>
Delivery & Returns
</button>
{activeTab}
</div>
</div>
)
}
CodePudding user response:
I found solution which is more simple and requires alot less code. Inside of the component I can just conditionally render by checking what activeIndex is equal to and return the component I would like.
{
activeIndex === 1 ? <Today/> :
activeIndex === 2 ? <Tomorrow /> :
<SevenDays/>
}