React.JS 中如何实现独立组件之间的通信
介绍
在 React 组件之间传递数据有多种方式:
- 渲染道具/道具
- 语境
- React-Redux/Redux
本指南将重点介绍 React 组件之间的不同通信方式。在每种方法中,我们都希望实现双向通信:
- 父母对孩子
- 孩子对父母
渲染道具/道具
使用 props 来向 React 组件传递数据是最方便的方式。
什么是 prop?我们在组件中的标记定义如下:
class Child extends React.Component {
render() {
return (
<div>
Child component
</div>
)
}
}
class Parent extends React.Component {
render() {
return (
<Child />
)
}
}
这将导致:
Child component
Parent是Child的父组件;Child是Parent的子组件,并且Child实际上是在Parent内部渲染的。Parent可以渲染Child 的方式如下:
class Parent extends React.Component {
render() {
return (
<Child name="chrisps" />
)
}
}
Parent在组件Child中添加了一些额外的东西。这类似于在 HTML div 中添加 ID,例如<div id=”d1”></div> 。ID属性有一个值chrisps。实际上,每个元素都是HTMLElement类的对象。
浏览器引擎解析上述div标签,结果为每个标签创建HTMLElement实例。HTML 中的每个标签都与相应的HTMLElement相关联:
div -> HTMLDivElement
anchor -> HTMLAnchorElement
body -> HTMLBodyElement
button -> HTMLButtonElement
...
所有这些 HTMLElement 都有一个超类 HTMLElement。这些 HTMLElement 的方法和属性用于渲染目的和操作数据。
HTML*Element
- appendChild
- attributes
- getAttribute
- hasAttribute
- innerHTML
- innerText
- setAttribute
...
上面的例子将产生如下所示的HTMLDivElement :
const divElement = new HTMLDivElement()
divElement.setAttribute("name", "chrisps")
props 对象将设置属性名称,如下所示:
props = {
name: "chrisps"
}
这将由 React 传递给Child组件类。
class Child extends React.Component {
constructor(props) { }
...
}
然后它将使用this.props.name启用对Child组件的属性值的访问:
class Child extends React.Component {
constructor(props) {
log(this.props.name) // chrisps
}
...
}
由于 React 基于 JSX,Parent的编译结果如下:
<Child name="chrisps" />
|
|
|
|
v
React.createElement(Child, { name:"chrisps" })
React createElement的第一个参数是要渲染的元素。第二个参数表示具有元素属性的对象。createElement 的输出是包含这两个参数的对象文字。对象文字可以是实际元素或类。React 在渲染过程中检查对象文字。如果对象文字是一个类,React 将使用传入 props 对象的关键字new实例化该类并调用 render 函数。
const objType = React.createElement(Child, { name:"chrisps" })
if(IS_ELEMENT(objType)) {
//...
}
else {
if(IS_CLASS(objType)){
const klass = objType.component;
// klass holds the Child class "class Child extends React.Component {...}"
const props = objType.props;
// props contains { name: "chrisps" }, the attributes passed to Child component in Parent component "<Child name="chrisps" />"
const k = new klass(props);
// here, it(klass) is instantiated and props is passed to it.
k.componentWillMount();
k.render();
k.componentDidMount();
//...
}
}
上面的代码展示了 React 如何渲染一个组件或元素。需要注意的是,该代码仅展示了组件如何接收 props 参数。首先要检查objType是类还是元素。IS_ELEMENT (…)方法将其与所有 HTML 元素列表进行比较。如果与其中一个元素相同,则返回true,表示 objType是一个元素。否则可以推断它是一个类。如果 objType是类,它会从objType中解构 props 和 class。然后它使用关键字new创建该类的对象并传入 props。因此,我们可以看到组件Parent已将数据发送给Child。Child 如何将数据发回给Parent?它使用 render props 方法将数据发回给其父级Parent。
什么是 render props? 它是一个将函数作为 props 传递给子组件的概念。它可以是作为 props 传递给子组件的字符串、对象、数字或数组。函数也可以通过以下方式作为 props 传递:
<Child func={() => {log("render props...")}} />
class Child extends React.Component {
constructor(props){
this.props.func()
}
render() {
return (
<div>
{this.props.func()}
</div>
)
}
}
在上面的代码中,使用名为 func 的 prop将函数{} => {log{“render props”}}传递给Child组件。Child组件可以通过 props 中的func使用此函数。我们知道它是一个函数,我们可以通过添加()来调用它。然后我们可以看到 render props 被记录到控制台。现在我们已经熟悉了 render props 的工作原理,让我们研究一下 child 组件,看看它如何将数据发送给父组件。
class Parent extends React.Component {
constructor() {
this.output = this.output.bind(this)
}
output() {
log("Hi there from React component !")
}
render() {
return (
<Child func={this.output} />
)
}
}
class Child extends React.Component {
constructor(props) {}
render() {
return (
<div>
Child component
<button onClick={this.props.func}>Send Data To Parent</button>
</div>
)
}
}
Parent组件有一个绑定到其实例的方法。 bind(this)的使用限制了 JS 在类、对象或函数的范围内运行该函数。因此,即使在 Parent 类之外运行,该函数仍然可以访问Parent类中定义的属性和方法。 输出方法被传递给组件Child 。组件Child可以通过 props 中的 func 属性访问它。 Child组件有一个按钮Send to Parent,并设置了关联的onclick事件来调用输出方法。现在,组件Child中的this.props.func将调用组件Parent中的输出方法:<
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~