I'm building a Wizard/Steps component where every child component is a step, the Steps component find the current step that should be show and renders it wrapped in a provider.
I next step I want to achieve is a component to be rendered during all steps. I achieve through the child components props before be render, so that way I could work with the components like this:
<Steps >
<Text> Step 1 </Text>
<Text> Step 2 </Text>
<Text stepless > Stepless </Text>
</Steps>
I achieve it by coding Steps component like this.
export const Steps: React.FC<types.Steps> = ({ step = 0, ...properties }) => {
/**
* Global state that store the total number of steps and the current step
*/
const steps = React.Children.count(properties.children)
const [state, dispatch] = useReducer(reducer, { step, steps })
/**
* Function that will let child components to change the current step
*/
const next = () => dispatch(types.Action.NEXT)
const previous = () => dispatch(types.Action.PREVIOUS)
/**
* Value to provide to the provider
* next and previous function to change the current step
* and the current step
*/
const value = { next, previous, step: state.step }
/**
* Filter the child components that should be shown
*/
const children = React.Children.toArray(properties.children)
.filter((child, index) =>
// @ts-ignore
(index === state.step) || child?.props.stepless
)
return (
<Context.Provider value={value} >
{ children.map((child, index) => <div key={ index } > { child } </div>) }
</Context.Provider>
)
}
But this code smells to me because child?.props
is not part of the types of react, this make me believe that is used internally and I not should be using it, but I not found other solution to filter components that should be shown over all the steps.
I'm looking for a different way to achieve the same behavior, without using //@ts-ignore
.