一些背景...
我正在使用 React 创建一个应用程序(效果很好),但对必须保留在父组件中的状态/函数数量感到沮丧。
我想做的是将一些状态和功能推送到子父组件,使其更易于管理。
我遇到问题的一个功能领域是需要在父组件的 JSX 中呈现的 Modal
组件。
此 Modal
我已使其可重用,因此它仅呈现 {this.props.children}
。内容由 switch case 语句决定,并根据其“模式”显示新组件的内容
问题...
不确定 React 中是否有这样的模式,但我想将一个函数及其参数通过 props 传递给另一个子组件,并让子组件将参数设置为渲染时的状态。
这是代码的简化版本,仅显示 1 个模态“模式/内容选项”:
import React, { Component } from "react";
import ReactDOM from "react-dom";
class Items extends Component {
state = {
categories: [
{
id: 1,
name: "category 1",
items: [
{ name: "item 1", id: Math.floor(Math.random() * 99999) },
{ name: "item 2", id: Math.floor(Math.random() * 99999) }
]
},
{
id: 2,
name: "category 2",
items: [
{ name: "item 3", id: Math.floor(Math.random() * 99999) },
{ name: "item 4", id: Math.floor(Math.random() * 99999) }
]
},
{
id: 3,
name: "category 3",
items: [
{ name: "item 5", id: Math.floor(Math.random() * 99999) }
]
}
],
modalOpen: true,
modalMode: ""
};
getClickedItem(item, category) {
console.log("[click from parent component]", arguments);
return arguments
};
openModal(mode, item, category) {
if (mode === "editItem") {
this.getClickedItem(item, category);
}
this.setState({
modalOpen: true,
modalMode: mode
});
}
closeModal() {
this.setState({
modalOpen: false,
modalMode: ""
});
}
render() {
const { categories, modalOpen, modalMode } = this.state;
let modalContent;
switch (modalMode) {
case "editItem":
modalContent = (
<Component1 closeModal={this.closeModal.bind(this)} getClickedItem={this.getClickedItem}/>
);
break;
default:
break;
}
return (
<div>
{categories.map(cat => {
return (
<ItemCategory
{...cat}
key={cat.id}
click={this.openModal.bind(this)}
/>
);
})}
<Modal show={modalOpen}>{modalContent}</Modal>
</div>
);
}
}
class ItemCategory extends Component {
handleClick(item, category) {
this.props.click("editItem", item, category);
}
render() {
const { items, name } = this.props;
const getItems = items.map(item => {
return item;
});
return (
<div>
<div>-{name}</div>
<ul>
{getItems.map(item => {
return (
<li
key={item.id}
onClick={() => this.handleClick(item, name)}
>
{item.name}
</li>
);
})}
</ul>
</div>
);
}
}
class Component1 extends Component {
state = {
item: "",
category: ""
}
static getDerivedStateFromProps(props, state) {
const getParams = props.getClickedItem()
console.log("[from child component]", getParams)
}
render() {
const { item, category } = this.state;
const { closeModal } = this.props;
return (
<div>
<h1>Component1 modal content</h1>
<button onClick={closeModal}>Close</button>
{item}
{category}
</div>
);
}
}
class Modal extends Component {
render() {
return (
<div
style={{
transform: this.props.show
? "translateY(0)"
: "translateY(-100vh)",
opacity: this.props.show ? "1" : "0"
}}
>
{this.props.children}
</div>
);
}
}
function App() {
return <Items />;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
也可用作代码笔 https://codesandbox.io/s/m7jm5z0w4j
我认为该函数似乎可以很好地传递给子组件!但我无法使用父组件的参数。
任何对此的见解都会很棒,如果您需要更多详细信息,请告诉我。
谢谢:)
最佳答案
问题出在 openModal 和 closeModal 上吗?
定义如下函数:
openModal = () => {
this.setState({
modalOpen: true
});
}
然后将其作为 prop 传递,如下所示
click={() => this.openModal()}
<小时/>
说明
我编写函数的方式实际上等同于这样编写函数
constructor() {
this.openModal = this.openModal.bind(this)
}
openModal() {
this.setState({modalOpen: true})
}
不同之处在于我使用了粗箭头函数。
您可以像这样调用函数 this.openModal()
然后你必须将函数作为 prop 传递。如果您将其作为 this.openModal
传递,则子组件无法访问父状态,但如果您将其作为 () => this.openModal()
传递,则函数的效果是在传递之前计算的,这应该可行。这种传递函数的方式也适用于 Angular。
更新
在这个函数中
getClickedItem(item, category) {
console.log("[click from parent component]", arguments);
return arguments
};
参数未定义。
此外,您的 openModal 函数接受三个参数,但您没有传递任何参数。
实际上你的代码看起来不会像现在这样工作......但是,是的,将函数 Prop 作为胖箭头函数传递
<小时/>工作 - 我相当显着地改变了你的代码
import React, { Component } from "react";
import ReactDOM from "react-dom";
class Items extends Component {
state = {
categories: [
{
id: 1,
name: "category 1",
items: [
{ name: "item 1", id: Math.floor(Math.random() * 99999) },
{ name: "item 2", id: Math.floor(Math.random() * 99999) }
]
},
{
id: 2,
name: "category 2",
items: [
{ name: "item 3", id: Math.floor(Math.random() * 99999) },
{ name: "item 4", id: Math.floor(Math.random() * 99999) }
]
},
{
id: 3,
name: "category 3",
items: [{ name: "item 5", id: Math.floor(Math.random() * 99999) }]
}
],
modalOpen: false,
selectedItem: {}
};
openModal = item => {
this.setState({
modalOpen: true,
selectedItem: item
});
};
closeModal = () => {
this.setState({
modalOpen: false
});
};
render() {
const { categories, modalOpen, selectedItem } = this.state;
return (
<div>
{categories.map(cat => {
return (
<ItemCategory
{...cat}
key={cat.id}
click={item => this.openModal(item)}
/>
);
})}
<Modal show={modalOpen}>
<Component1
closeModal={() => this.closeModal()}
item={selectedItem}
/>
</Modal>
</div>
);
}
}
class ItemCategory extends Component {
handleClick = item => {
this.props.click(item);
};
render() {
const { items, name } = this.props;
const getItems = items.map(item => {
return item;
});
return (
<div>
<div>-{name}</div>
<ul>
{getItems.map(item => {
return (
<li key={item.id} onClick={() => this.handleClick(item)}>
{item.name}
</li>
);
})}
</ul>
</div>
);
}
}
class Component1 extends Component {
render() {
const { item, closeModal } = this.props;
console.log(item);
return (
<div>
<h1>{item.name} modal content</h1>
<button onClick={closeModal}>Close</button>
</div>
);
}
}
class Modal extends Component {
render() {
return (
<div
style={{
transform: this.props.show ? "translateY(0)" : "translateY(-100vh)",
opacity: this.props.show ? "1" : "0"
}}
>
{this.props.children}
</div>
);
}
}
function App() {
return <Items />;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
关于javascript - React - 从父级到子级访问函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52443156/