gpt4 book ai didi

javascript - 在 React.js 中将 props 传递给父组件

转载 作者:IT老高 更新时间:2023-10-28 13:12:08 26 4
gpt4 key购买 nike

有没有简单的方法可以传递 child 的props在 React.js 中使用事件到它的父级?

var Child = React.createClass({
render: function() {
<a onClick={this.props.onClick}>Click me</a>
}
});

var Parent = React.createClass({
onClick: function(event) {
// event.component.props ?why is this not available?
},
render: function() {
<Child onClick={this.onClick} />
}
});

我知道您可以使用受控组件来传递输入的值,但最好传递整个 kit n'kaboodle。有时子组件包含一组您不想查找的信息。

也许有一种方法可以将组件绑定(bind)到事件?

更新 – 2015 年 9 月 1 日

在使用 React 一年多之后,在 Sebastien Lorber 的回答的激励下,我得出结论,将子组件作为参数传递给父组件中的函数实际上并不是 React 的方式,也不是一个好主意。我已经换了答案。

最佳答案

编辑 :请参阅 ES6 更新示例的最终示例。

这个答案只是处理直接父子关系的情况。当 parent 和 child 可能有很多中间人时,请检查此 answer .

其他解决方案没有捕获重点

虽然它们仍然可以正常工作,但其他答案缺少一些非常重要的东西。

Is there not a simple way to pass a child's props to its parent using events, in React.js?



parent 已经有了那个 child Prop ! : 如果 child 有一个 Prop ,那是因为它的 parent 把那个 Prop 提供给了 child !为什么你想让 child 把 Prop 传回给 parent ,而 parent 显然已经有了那个 Prop ?

更好的实现

child : 它真的不必比这更复杂。
var Child = React.createClass({
render: function () {
return <button onClick={this.props.onClick}>{this.props.text}</button>;
},
});

单亲家长 : 使用它传递给 child 的值
var Parent = React.createClass({
getInitialState: function() {
return {childText: "Click me! (parent prop)"};
},
render: function () {
return (
<Child onClick={this.handleChildClick} text={this.state.childText}/>
);
},
handleChildClick: function(event) {
// You can access the prop you pass to the children
// because you already have it!
// Here you have it in state but it could also be
// in props, coming from another parent.
alert("The Child button text is: " + this.state.childText);
// You can also access the target of the click here
// if you want to do some magic stuff
alert("The Child HTML is: " + event.target.outerHTML);
}
});

JsFiddle

带有 child 列表的父级 :您仍然拥有父级所需的一切,不需要让子级变得更复杂。
var Parent = React.createClass({
getInitialState: function() {
return {childrenData: [
{childText: "Click me 1!", childNumber: 1},
{childText: "Click me 2!", childNumber: 2}
]};
},
render: function () {
var children = this.state.childrenData.map(function(childData,childIndex) {
return <Child onClick={this.handleChildClick.bind(null,childData)} text={childData.childText}/>;
}.bind(this));
return <div>{children}</div>;
},

handleChildClick: function(childData,event) {
alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
alert("The Child HTML is: " + event.target.outerHTML);
}
});

JsFiddle

也可以使用 this.handleChildClick.bind(null,childIndex)然后使用 this.state.childrenData[childIndex]
请注意,我们绑定(bind)了 null上下文,否则 React 会发出与其 autobinding 相关的警告系统。使用 null 意味着您不想更改函数上下文。 See also .

关于其他答案中的封装和耦合

这是给我的 耦合和封装方面的想法:
var Parent = React.createClass({
handleClick: function(childComponent) {
// using childComponent.props
// using childComponent.refs.button
// or anything else using childComponent
},
render: function() {
<Child onClick={this.handleClick} />
}
});

使用 Prop :
正如我上面所解释的,您已经在父组件中拥有了 props,因此传递整个子组件来访问 props 是没有用的。

使用引用 :
您已经在事件中拥有了点击目标,并且在大多数情况下这已经足够了。
此外,您可以直接在 child 上使用 ref :
<Child ref="theChild" .../>

并访问父节点中的 DOM 节点
React.findDOMNode(this.refs.theChild)

对于更高级的情况,您要访问父级中子级的多个引用,子级可以直接在回调中传递所有 dom 节点。

组件有一个接口(interface)(props),父组件不应该对子组件的内部工作做任何假设,包括它的内部 DOM 结构或它声明了 refs 的 DOM 节点。使用子项的 ref 的父项意味着您将两个组件紧密耦合。

为了说明这个问题,我将引用有关 Shadow DOM 的引用。 ,用于在浏览器中渲染滑块、滚动条、视频播放器等内容:

They created a boundary between what you, the Web developer can reach and what’s considered implementation details, thus inaccessible to you. The browser however, can traipse across this boundary at will. With this boundary in place, they were able to build all HTML elements using the same good-old Web technologies, out of the divs and spans just like you would.



问题是,如果让子实现细节泄漏到父中,则很难在不影响父的情况下重构子。这意味着作为库作者(或作为使用 Shadow DOM 的浏览器编辑器)这是非常危险的,因为您让客户端访问太多,这使得在不破坏复古兼容性的情况下升级代码变得非常困难。

如果 Chrome 实现了它的滚动条,让客户端访问该滚动条的内部 dom 节点,这意味着客户端可能有可能简单地破坏该滚动条,并且当​​ Chrome 在重构后执行其自动更新时,应用程序将更容易中断滚动条...相反,它们只允许访问一些安全的东西,比如用 CSS 自定义滚动条的某些部分。

关于使用其他任何东西

在回调中传递整个组件是危险的,可能会导致新手开发人员做一些非常奇怪的事情,比如调用 childComponent.setState(...)childComponent.forceUpdate() ,或在父级内部为其分配新变量,从而使整个应用程序更难以推理。

编辑:ES6 示例

由于现在很多人使用 ES6,这里是 ES6 语法的相同示例

child 可以很简单:
const Child = ({
onClick,
text
}) => (
<button onClick={onClick}>
{text}
</button>
)

父级可以是一个类(它最终可以管理状态本身,但我在这里将它作为 Prop 传递:
class Parent1 extends React.Component {
handleChildClick(childData,event) {
alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
alert("The Child HTML is: " + event.target.outerHTML);
}
render() {
return (
<div>
{this.props.childrenData.map(child => (
<Child
key={child.childNumber}
text={child.childText}
onClick={e => this.handleChildClick(child,e)}
/>
))}
</div>
);
}
}

但是如果不需要管理状态,也可以简化:
const Parent2 = ({childrenData}) => (
<div>
{childrenData.map(child => (
<Child
key={child.childNumber}
text={child.childText}
onClick={e => {
alert("The Child button data is: " + child.childText + " - " + child.childNumber);
alert("The Child HTML is: " + e.target.outerHTML);
}}
/>
))}
</div>
)

JsFiddle

性能警告 (适用于 ES5/ES6):如果你使用的是 PureComponentshouldComponentUpdate ,上述实现默认不会优化,因为使用 onClick={e => doSomething()} ,或者在渲染阶段直接绑定(bind),因为它会在每次父渲染时创建一个新函数。如果这是您的应用程序中的性能瓶颈,您可以将数据传递给子项,并将其重新注入(inject)“稳定”回调中(在父类上设置,并在类构造函数中绑定(bind)到 this),以便 PureComponent可以开始优化,或者您可以实现自己的 shouldComponentUpdate并忽略 Prop 比较检查中的回调。

您也可以使用 Recompose库,提供更高阶的组件以实现微调优化:
// A component that is expensive to render
const ExpensiveComponent = ({ propA, propB }) => {...}

// Optimized version of same component, using shallow comparison of props
// Same effect as React's PureRenderMixin
const OptimizedComponent = pure(ExpensiveComponent)

// Even more optimized: only updates if specific prop keys have changed
const HyperOptimizedComponent = onlyUpdateForKeys(['propA', 'propB'])(ExpensiveComponent)

在这种情况下,您可以使用以下方法优化 Child 组件:
const OptimizedChild = onlyUpdateForKeys(['text'])(Child)

关于javascript - 在 React.js 中将 props 传递给父组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22639534/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com