如何通过React Context API实现组件的传递与渲染?
Hey there! Let's break down why your components aren't showing up on the Board even though you can see the array has content in the console.
核心问题:Map函数未返回元素
Looking at your Board component code, the issue is right in the map call:
{components.map((component, i) => { <div className="h-40 w-40 bg-gray-500 z-50" key={i}> {component}</div> })}
When you use curly braces {} for the arrow function body, you need to explicitly return the JSX element. Right now, each iteration returns undefined, so nothing gets rendered to the DOM.
修复方法
You have two easy fixes here:
- Implicit return with parentheses:
{components.map((component, i) => ( <div className="h-40 w-40 bg-gray-500 z-50" key={i}> {component} </div> ))}
- Explicit return statement:
{components.map((component, i) => { return ( <div className="h-40 w-40 bg-gray-500 z-50" key={i}> {component} </div> ) })}
After making either change, your Todo components should start showing up on the Board.
优化建议:不要直接存储React元素
While storing React elements directly in the Context array works, it's not the most flexible or performant approach. A better pattern is to store component configuration objects instead, which lets you dynamically render components and pass props easily.
Here's how to refactor:
- Update the Context's setComponent function:
// Adjust the type to accept component configs type ComponentConfig = { type: 'todo' | 'image' | 'table'; props?: Record<string, any>; }; const setComponent = (config: ComponentConfig) => { setComponents(prev => [...prev, config]); };
- Modify the menu click handler to pass configs:
<button id="Todo" onClick={() => setComponent({ type: 'todo', props: { initialItems: ['Task 1', 'Task 2'] } })} className={`${ active ? "bg-blue-500 text-white" : "text-black" } flex items-center py-2 px-3 rounded-lg w-full`} > {/* ...icon and text */} </button>
- Render components dynamically in the Board:
// Create a map of component types to actual components const ComponentMap = { todo: Todo, // Add other components here, e.g., image: ImageComponent, table: TableComponent }; // Then render using the config {components.map((config, i) => { const Component = ComponentMap[config.type]; if (!Component) return null; // Handle unknown types gracefully return ( <div className="h-40 w-40 bg-gray-500 z-50" key={i}> <Component {...config.props} /> </div> ); })}
This approach gives you more control: you can pass different props to each component instance, easily add new component types, and keep your state lightweight.
内容的提问来源于stack exchange,提问作者ckam03

