React组件传值
(一)父传子
传递:在父组件中子组件的标签上,给子组件绑定一个自定义属性,值为需要传递的数据
接收:在子组件内部通过props进行接收
- 如何限制外部数据的类型
https://react.docschina.org/docs/typechecking-with-proptypes.html
- 安装
prop-types
cnpm install prop-types
- 引入PorpTypes
import ProtoTypes from “prop-types”
- 配置
组件名称.propTypes = {
属性名称 : PropTypes.类型
}
- 如何定义外部数据的默认值
组件名称.defaultProps = {
属性名称 : 默认值
}
详见下面案例中的one.js
(二)子传父
传递:在子组件内部通过调用this.props.事件函数名称来进行传值
接收:在父组件中子组件的标签上,给子组件绑定一个自定义属性,值为需要传递的数据
(三)非父子
手动封装Observer(事件订阅)
传值的一方调用
Observer.$emit
,使用Observer.$on
接收
- 组件传值案例
组件传值.png
- index.jsx
import React, { Fragment } from "react";
import One from "./components/one"
import Two from "./components/two"
class App extends React.Component {
constructor() {
super();
this.state = {
msg: "app组件",
value: ""
}
}
render() {
return (
<div className="app">
<h2>app组件</h2>
<h2>接收到子组件的值为:{this.state.value}</h2>
<One username={this.state.msg} />
<Two handle={this.handleTwo.bind(this)} />
</div>
)
}
handleTwo(value) {
this.setState({
value
})
}
}
export default App;
- one.js
import React, { Component } from "react"
import Three from "./three"
import PropTypes from "prop-types"
class One extends Component {
render() {
let { username } = this.props;
return (
<div className="One">One组件
<h2>接受到父组件的值为:{username}</h2>
<Three />
</div>
)
}
}
One.proTypes = {
username:ProTypes.string
}
One.defaultProps = {
username:"默认值"
}
export default One
- two.js
import React, { Component } from "react"
import Observer from "../observer"
class Two extends Component {
constructor() {
super();
this.state = {
threeVal: ""
}
Observer.$on("handle", (value) => {
this.setState({
threeVal: value
})
})
}
render() {
return (
<div className="Two">
Two组件
<h2>接收到three组件的值为:{this.state.threeVal}</h2>
<button onClick={this.handleAdd.bind(this)}>点击发送给父组件</button>
</div>
)
}
handleAdd() {
this.props.handle('two组件')
}
}
export default Two
- three.js
import React, { Component } from "react"
import Observer from "../observer"
class Three extends Component {
render() {
console.log(1, this)
return (
<div className="three">
three组件
<button onClick={this.handleSend.bind(this)}>发送到two组件</button>
</div>
)
}
handleSend() {
Observer.$emit("handle", "three组件");
}
}
export default Three
(四)context
Provider-Consumer跨组件传值,相当于vue中的provide/reject
通过context创建一个生产者作为父级,再创建一个消费者组件作为子级使用。
- Consumer必须要有一个函数,返回一个jsx语法
Provider-Consumer.png
- createContext.js
import React, { createContext } from "react";
export let { Provider, Consumer } = createContext();
- index.jsx
import React, { Fragment } from "react";
import One from "./components/one"
import { Provider } from "./createContext"
class App extends React.Component {
render() {
return (
<Provider
value={{
username: "lxc",
age: 18
}}
>
<div className="app">
app组件
<One />
</div>
</Provider>
)
}
}
export default App;
- two.jsx
import React, { Component } from "react"
import { Consumer } from "../createContext"
class Two extends Component {
render() {
return (
<Consumer>
{
(props) => {
return (
<div className="Two">
two组件
<h2>接收app组件传值username:{props.username} </h2>
</div>
)
}
}
</Consumer>
)
}
}
export default Two