react2.0
react脚手架安装
安装react之前,你首先要先确保你安装了node.js
地址:https://nodejs.org/zh-cn/
安装时,记得勾选Add to Path
查看node版本:node -v
查看npm版本:npm -v
方式:
1.npm init react-app 项目名
npm install -g create-react-app
2.yarn create react-app 项目名
删掉项目中一些不必要的东西:src文件夹下的文件,只剩app.js和index.js就可以;有需要的可以再创建
组件传值
组件是独立且封闭的单元,要接受外部的数据应该通过props来实现
props的作用:接收传递给组件的数据
传递数据:给组件标签添加属性
接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据
City组件
import React from "react"
// 类组件
/* class City extends React.Component {
render() {
return (
<div>中午好困</div>
)
}
} */
// 函数组件(箭头函数形式)
//箭头函数模式简写
// const City = () =><div>下午好</div>
const City = (props) => {
return (
<div>下午好{ props.list[0]},{ props.list[1]}现在在干嘛,{ props.list[2]}在干饭,{ props.list[3]}在加班打代码</div>
)
}
export default City
App组件
import React from "react"
// 组件是封闭,要接受外部的数据应该通过props来实现
// props接受传递给组件的数据
// 类组件
class App extends React.Component {
constructor(props) {
super(props)
// Useless constructor no-useless-constructor
// 要添加state
this.state = {}
}
render() {
return (
<div>你吃饭了吗?我今天吃了{ this.props.eat}</div>
)
}
}
export default App
入口文件index.js
// 入口文件
import React from 'react';
import ReactDOM from 'react-dom';
import City from "./components/city"
import App from "./App"
function Hello(props) {
return (
<div>我是函数组件——{ props.uname}</div>
)
}
// 传递数组的话,数组外面要加{}
ReactDOM.render(
<div><City list={ ['张三','李四','王五','周六']}/><App eat='螺蛳粉'/><Hello uname='zs'/></div>,
document.getElementById('root')
);
1.可以给组件传递任意类型的数据
2.props是只读的对象,只能读取属性的值,无法修改对象
3.注意:使用类组件时,如果写了构造函数,应该将props传递给super(),否则无法在构造函数中获取到pros
父组件传子组件
import React from "react"
// 组件传值——父传子
// 父组件-类组件
class Person extends React.Component {
state = {
msg:'我是人类的类组件'
}
render() {
return (
<div>
我是人类
<Stu msg={ this.state.msg} />
</div>
)
}
}
// 子组件-函数组件
function Stu(props) {
return (
<div>我是学生类函数组件——{ props.msg}</div>
)
}
export default Person
入口文件
// 入口文件
import React from 'react';
import ReactDOM from 'react-dom';
// 父传子
import Person from "./components/stu"
// 传递数组的话,数组外面要加{}
ReactDOM.render(
<div><Person /></div>,
document.getElementById('root')
);
子组件传父组件
思路:利用回调函数,组组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
1.子组件标签绑定属性(info),属性值是父组件的回调函数(this.getInfo),用于接收数据,将值给子组件(父传子)
2.子组件绑定一个事件(handle),子组件通过props调用父组件的回调函数(this.props.info)
3.将子组件的数据(this.state.msg)作为父组件回调函数的参数,传递给父组件
注意:回调函数中this的指向问题
// 入口文件
import React from 'react';
import ReactDOM from 'react-dom';
// 子传父
// 父组件
class Person extends React.Component {
// 父组件中的数据
state = {
msg:''
}
render() {
return (
<div>
子组件传递过来的数据:{ this.state.msg}
<Stu info={this.getInfo }/>
</div>
)
}
// 接收子组件传递过来的数据,参数msg是子组件调用回调函数的函数
getInfo=(msg)=> {
// 修改msg的值
this.setState({
msg:msg
})
}
}
// 子组件
class Stu extends React.Component {
// 子组件中的数据
state = {
msg:'我是学生类组件'
}
render() {
return (
<div>
<button onClick={this.handle}>传值给父组件</button>
</div>
)
}
// 这里的info是子组件的一个属性,属性值是父组件的回调函数
// this.props.info是一个回调函数,将this.state.msg作为参数传过去
handle = () => {
this.props.info(this.state.msg)
}
}
ReactDOM.render(
<div><Person /></div>,
document.getElementById('root')
);
无注释版:
import React from 'react';
import ReactDOM from 'react-dom';
// 子传父
// 父组件
class Person extends React.Component {
state = {
msg:''
}
render() {
return (
<div>
子组件传递过来的数据:{ this.state.msg}
<Stu info={ this.getInfo}/>
</div>
)
}
getInfo = (msg) => {
this.setState({
msg:msg
})
}
}
// 子组件
class Stu extends React.Component {
state = {
msg:'我是子组件传递给父组件的数据'
}
render() {
return (
<div>
<button onClick={this.handle}>传值</button>
</div>
)
}
handle = () => {
this.props.info(this.state.msg)
}
}
ReactDOM.render(
<div><Person /></div>,
document.getElementById('root')
);
兄弟组件
状态组件:将共享状态提升到最近的公共组件中,由公共父组件管理这个状态
公共父组件职责:1.提供共享状态;2.提供操作共享状态的方法
要通讯的子组件只需通过props接收状态或操作状态的方法
import React from 'react';
import ReactDOM from 'react-dom';
// 子传父
class Counter extends React.Component {
state = {
num: 1
}
render() {
return (
<div>
<Child1 num={this.state.num} />
<Child2 handle={this.addNum} />
</div>
)
}
addNum = () => {
this.setState({
num: this.state.num + 1
})
}
}
const Child1 = (props) => {
return (
<div>
{props.num}
</div>
)
}
const Child2 = (props) => {
return (
<div>
<button onClick={() => {props.handle() }}>+1</button>
</div>
)
}
ReactDOM.render(
<div><Counter /></div>,
document.getElementById('root')
);
Context
父组件要传递数据给子组件,通过props一层层组件往下传递(繁琐),使用Context
作用:跨组件传值,
1.调用React.createContext(),创建Provider(提供数据)和Consumer(消费数据)两个组件
2.使用Provider组件作为父节点,设置value属性,属性值就是要传递的数据
3.调用Consumer组件接受数据
import React from 'react';
import ReactDOM from 'react-dom';
// Provider:提供数据
// Consumer:消费数据,Consumer组件内部是一个回调函数(箭头函数)
const { Provider, Consumer } = React.createContext()
// Provider中的属性value只能有一个,传递什么都可以
class App extends React.Component {
render() {
return (
<div>
<Provider value='hello,react'>
<Node />
</Provider>
</div>
)
}
}
const Node = () => {
return (
<div className='Node'>
<SubNode />
</div>
)
}
const SubNode = () => {
return (
<div className='SubNode'>
<Child />
</div>
)
}
// 这里面的data就是Provider组件中的value属性的属性值
const Child = () => {
return (
<div>
<Consumer>{data => <span>我是子节点————{ data}</span>}</Consumer>
</div>
)
}
ReactDOM.render(
<div><App /></div>,
document.getElementById('root')
);
总结:1.如果两个组件是远方亲戚(嵌套多层),可以使用Context实现组件通讯
2.Context提供了两个组件:Provider和Consumer
3.Provider组件用来提供数据
4.Consumer组件是用来消费数据
props深入
1.children属性
children属性:表示组件标签的子节点,当组件标签有子节点时,props就会有该属性
children属性和普通的props一样,值可以是任意值(文本、react元素、组件、甚至是函数)
import React from 'react';
import ReactDOM from 'react-dom';
// {props.children}相当于vue的中的插槽slot
// props.children就是组件标签内的内容
const App = (props) => {
return (
<div>
组件的子节点:{props.children}
</div>
)
}
ReactDOM.render(
<div><App>你是一个干饭人</App></div>,
document.getElementById('root')
);