Reputation: 457
I want to change the text of a child function component when I hover over a button of my parent class component. I'm having trouble accessing the prop though in the child component and getting null. Any help is appreciated
parent component:
export default class PathfindingVisualizer extends React.Component {
constructor(props) {
super(props)
this.state = {
AlgoDef: null,
};
}
render() {
return (
<React.Fragment>
<div className="button-bar"> //buttons that change state
<button
onClick={() => this.helperDikjstras()}
onMouseOver={() => this.setState({ AlgoDef: "Dikj"})}
>Dikjstras</button>
<button
onClick={() => this.helperAstar()}
onMouseOver={() => this.setState({ AlgoDef: "Astar"})}
>A*</button>
</div>
<div>
<AlgoExplaination algoName={this.AlgoDef} /> //changes its text based on state of parent
</div>
</React.Fragment>
);
}
}
my child component:
export default function AlgoExplaination(props) {
const [text, setText] = useState("default");
useEffect(() => {
switch (props) {
case "Dikj":
setText("Dikjstra");
break;
case "Astar":
setText("Astar");
break;
default:
setText("useEff");
}
//console.log(`text: ${text}`);
//console.log(props);
// console.log(props.algoName);
});
return (
<div>
<p>{text}</p>
</div>
)
}
both console logging props
gives me: {algoName: null}
. and props.algoName
gives me null
Upvotes: 0
Views: 681
Reputation: 24915
As @Wyck has addressed most of the points, I'll focus this answer on the last point:
Third, why do you have both class component and functional component with hooks? Please use 1 way
In theory, a class component has lifecycle events and state, where as a functional component is just a function that returns JSX.Element
. Such components were called stateless.
Because of this, class component had a bit of overhead over functional component, and as a performant option functional component were preferred.
Hooks are a way in react to give functional components access to have its own state and few major lifecycle events. This is achieved using closure (not going in full depth) and craftsmanship. This also makes class components obsolete as everything can be achieved in functional component.
As a preference, its suggested to use functional component with hooks as they are easy to use and are performant as well, in comparison.
In general programming practice, as a developer, you should use a single way to do things. Benefit of this is, it helps in fast reading.
If I use a for
loop in one section and a Array.forEach
in next, as a developer, I will be asked to read and understand the purpose. This adds overhead and reduces readability. Having same approach moves the focus of reader to just the logic.
Upvotes: 1
Reputation: 97
I recomend you to destructuring the props, to be more clear.
In
export default function AlgoExplaination(props)
Can be something like:
export default function AlgoExplaination({algoName})
So you can use it in your switch statment.
switch (algoName) {
case "Dikj":
setText("Dikjstra");
Right now, you are passing all props but you will have to access as props.algoName in the switch statment.
Upvotes: 0
Reputation: 11730
As @Rajesh has mentioned in a comment, you are passing props to your AlgoExplaination
(sic) component incorrectly like this:
<AlgoExplaination algoName={this.AlgoDef} />
You intended to pass the AlgoDef
property of your state, which is this.state.AlgoDef
, so change accordingly to this:
<AlgoExplaination algoName={this.state.AlgoDef} />
Furthermore, when you access the algoName
property of your props, you currently attempt to access it as if it were the props object itself incorrectly like this:
switch (props) {
The props
object for AlgoExplaination
will be an object with an algoName
property that looks (partially) like this:
{ algoName: "Dikj" }
So, the value you need is actually stored in props.algoName
. Therefore, please change accordingly to this:
switch (props.algoName) {
Upvotes: 1