Some experimentation I'm doing with React has gotten me the following code:
const BreadNav = props => {
const initial={
stack:[
{
name:"Home",
render:React.cloneElement(
props.children,
{pushElement:pushElement}
),
state:{}
}
],
};
const [state, setState] = React.useState(initial);
const pushElement = (oldState,elem) => {
let newStack = JSON.parse(JSON.stringify(state.stack));
newStack[newStack.length-1].state = oldState;
newStack.push(elem);
setState({
...state,
stack:newStack
});
}
return(
state.stack[state.stack.length-1].render
);
}
React gives me ReferenceError: can't access lexical declaration 'pushElement' before initialization
which makes sense for the order the lines are in. If this was C, I would just throw in a function prototype to declare pushElement
and define it later, but I haven't seen a javascript answer for this. How do I avoid this trouble?
You can use a function declaration, which is "hoisted", instead of assigning a function value to a const
variable:
function BreadNav(props) {
const initial = {
stack: [
{
name: "Home",
render: React.cloneElement(props.children, {pushElement}),
state: {}
}
],
};
const [state, setState] = React.useState(initial);
function pushElement(oldState,elem) {
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
let newStack = JSON.parse(JSON.stringify(state.stack));
newStack[newStack.length-1].state = oldState;
newStack.push(elem);
setState({
...state,
stack: newStack
});
}
return state.stack[state.stack.length-1].render;
}
but in this case it would be much more appropriate to define the function before you use it in the initial
object literal:
const BreadNav = props => {
const pushElement = (oldState, elem) => {
let newStack = JSON.parse(JSON.stringify(state.stack));
newStack[newStack.length-1].state = oldState;
newStack.push(elem);
setState({
...state,
stack: newStack
});
};
const initial = {
stack: [
{
name: "Home",
render: React.cloneElement(props.children, {pushElement}),
state: {}
}
],
};
const [state, setState] = React.useState(initial);
return state.stack[state.stack.length-1].render;
}
You can still refer to the state
and setState
variables declared below, they are in scope, you just must make sure not to call the function before they are initialised.