2

I have a list of settings that are used as data to instantiate web components at runtime. Each time a settings object is added to the list using a button in the main < App /> the item is looked up and is rendered at runtime. That components are stored using use useContext.

// ComponentContext initial state
const initialState = {  components: [] } // components example state ['a', 'b', 'c']

// component source
export function getComponent(id) { 
    const ComponentA = () => {
       const [info] = useState([1,2,3]);
       return (<div>A</div>)
    }        
    const ComponentA = () => {
       const [info] = useState([3,4,5]);
       return (<div>A</div>)
    }        
    const componentMap = {
       a: ComponentA,
       b: ComponentB
    }
}

// App component
function App() {
    const { add, components }  = useContext(ComponentContext);

return <div className="flex">
  <button onClick={add('a')}>add a</button>
  <button onClick={add('b')}>add b</button>
  <button onClick={add('c')}>add c</button>
  {components.map(id => {
    const Component = componentMap[id];
    return <Component key={id}/>
  })}
</div>

Later on in the program I want to print out the component instance and the info array items. The info array items are unchanged after creation per component. The problem is that the components list saved in the component context doesn't contain information about the info array(might look like this ['a',b','a','c'... and so on] so I can't walk the hierarchy using the component list. Also, the info arrays are randomly generated at runtime and don't relate to the components themselves.

It looks like I should change my initialState to something like the following:

// ComponentContext initial state
// example state [{ id: 'a', info: [...] }, { id : 'c', info: [...] }]
const initialState = {  components: [] } 

Since add components method doesn't have access to the info arrays how can I set the info list at time of storing the newly added components?

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
jwize
  • 4,230
  • 1
  • 33
  • 51

1 Answers1

0

I think there is no way to access the components state from outside (at least no clean one).

"Context" is meant to be used for this purpose: to share state between components. The components own state (useState) should only store data which is needed solely by this one component.

I think you should design your parent state (ComponentContext) so that every component has access to all the data that it needs.

Also, you said "the info arrays ... don't relate to the components themselves", so I think the info should relate to something else, consequently it should be possible to store the data inside this "something else", and make the components receiving the data from there.

Instead of creating components with the add function, you could add data to some store. Then when you want to show the components, you would iterate (.map()) the store instead of the components list, and create the components 'on the fly'. In the same way you would access the same store where you want to "print out" the info.

kca
  • 4,856
  • 1
  • 20
  • 41
  • Of course the lists relate to the components themselves otherwise I wouldn't put them there. I said random because each type of component has a different list which is not random but unique to the component. – jwize Dec 14 '20 at 22:58