javascript - React - 使用 Context API 通过另一个组件更改多个单独的组件
问题描述
假设我有三个组件App
:Block
和BlockOptions
。
App
有一个名为的数组blocks
,它包含所有块组件。这些块在某种画板内渲染。因为每个块都可以修改,所以我想在选择BlockOptions
a 时充当属性面板Block
。那Block
应该可以从那里修改。请记住,这BlockOptions
是在一个完全不同的位置。
应用程序.js:
class App extends Component {
constructor(props) {
super(props)
this.state = {
artboardSize: {
width: 300,
height: 200
},
blocks: []
}
}
// App component contains several methods that change the blocks array, like this one
addBlock(width, height) {
const newBlock = {
width: width,
height: height
}
this.setState(prevState => ({
blocks: [...prevState.blocks, newBlock]
}));
}
render() {
return (
<GlobalContext.Provider value={this}>
<div className="app">
<Artboard /> // Where all Blocks go
<Sidebar /> // Where BlockInfo goes
</div>
</GlobalContext.Provider>
)
}
}
如上所示,我使用 Context API 让所有组件都可以访问App
's 的状态和方法。因此,例如,如果单击页面上某处的按钮,该组件将调用App
'saddBlock()
方法来创建一个新块。
这就是我当前渲染每个块的方式Artboard
:
{context.state.blocks.map((block, key) => (
<Block key={key} width={block.width * context.scale} height={block.height * context.scale} />
))}
在 Block.js 中,我想在用户单击一个块时将App
's blocks 数组更改selected
为:true
class Block extends Component {
constructor(props) {
super(props);
this.state = {
width: this.props.width,
height: this.props.height,
selected: false
// etc...
}
}
handleOnClick() {
this.setState({
selected: true
});
// But how do I update this in App?
}
render() {
return (
<div className="block" onClick={() => this.handleOnClick()}></div>
)
}
}
但我不能。我可以更新 中的状态, Block
但不能更新整个应用程序本身。我该怎么做?
我对 React 很陌生。所以也许使用 Context API 不合适,我真的不知道。也许我的整个思维方式都搞砸了。也许有更好的方法来解决这个问题?
基本上我想要做的是: 拥有一组彼此不同的组件,以便能够从某种“选项面板”中进行更改。每个块都是不同的,所以这个面板应该根据所选块的状态而变化。
解决方案
无论您决定使用上下文、reducer 还是状态,您都需要将一个函数传递给您的块组件,该函数将被顶级组件调用以更新传递给子组件的值。
如果要使用上下文,可以将值更改为:
<GlobalContext.Provider value={{ blocks: this.state.blocks, addBlock: this.addBlock }} >
这样,上下文的任何消费者不仅可以访问这些块,而且还可以调用一个函数来为应用程序中的任何其他消费者更新它们。
{context.blocks.map((block, key) => <Block ... onAdd={context.addBlock} />)}
在块内:
handleOnClick() {
this.setState ...
this.props.onAdd();
}
推荐阅读
- java - Java - &0xff 将 8 到 31 的位作为 1
- python - 使用 pip install 安装语言检查时出错
- python-3.x - python multiprocessing:: 如何使用范式add_job_to_queue,处理队列(有N个worker)
- angular - Express 应用程序中的两个 Angular 应用程序(错误:无法匹配任何路由。URL 段:)
- r - 如何确定交互图中两组之间的显着性差异?
- typescript - 您可能需要适当的加载器来处理此文件类型,目前没有配置加载器来处理此文件(Storybook - React Native 和 TS:
- python - 如何阻止特定角色在 discord.py 中发言?
- python - 创建脚本以在推送到 S3 存储桶时替换文件中的值
- c++ - 计算存储为向量数组 C++ 的通用树的每个节点的高度
- python - 从字符串中提取单词到列表中 | Python