本文已参与[新人创作礼]活动,一起开启掘金创作之路
一.前言
这里默认你已经安装了react的环境准备,没有去官网
zh-hans.reactjs.org/docs/gettin…
可以先了解下JSX
二.组件
1.基本介绍
- 组件是React中最基本的内容,使用React就是在使用组件
- 组件表示页面中的部分功能
- 多个组件可以实现完整的页面功能
- 组件特点:可复用,独立,可组合
2.React创建组件的两种方式
(1)函数组件
是什么
使用JS的函数或者箭头函数创建的组件
要求
- 为了区分普通标签,函数组件的名称必须
大写字母开头 - 函数组件
必须有返回值,表示该组件的结构 - 如果返回值为null,表示不渲染任何内容
怎么用
/0 准备工作(类组件也许准备)
index.js
import App from './App';
root.render(
<App />
);
/1 箭头函数
App.js
import React from 'react'
const App=()=>{
return <div>666</div>
}
export default App
/2 函数
App.js
import React from 'react'
function App() {
return <div>666</div>
}
export default App
(2)类组件
了解
此处应有链接
是什么
使用ES6的class语法创建组件
要求
-
- 类名必须以大写字母开头
-
- extends是一个关键字,用来实现类之间的继承。类组件应该继承 React.Component 父类,从而使用父类中提供的方法或属性。
-
- 类组件必须提供 render 方法,render 方法必须有返回值,表示该组件的 UI 结构。render会在组件创建时执行一次
怎么用
import React from 'react'
class Com extends React.Component {
render() {
return
<div>
</div>
}
}
export default Com
3.提取组件(举例)
src\views\Class.js
import React from 'react'
class Class1 extends React.Component{
render(){
return (
<div>
Class
</div>
)
}
}
export default Class1
src\views\Hello.js
import React from 'react'
class Hello extends React.Component{
render(){
return (
<div>
Hello
</div>
)
}
}
export default Hello
src\App.js
import React from 'react'
import Hello from './views/Hello'
import Class1 from './views/Class'
class Com extends React.Component {
state={
sMsg:''
}
fatherFn=(msg)=>{
this.setState({
sMsg:msg
})
console.log('father',msg);
}
render() {
return <div>
App
<hr/>
<Hello/>
<hr/>
<Class1/>
</div>
}
}
export default Com
效果
4.存放数据的两种方式
(1)
constructor(){
super()
this.state={
name:666
}
}
了解
首先说一点,ES5和ES6的继承机制不同,ES5的继承实质是通过,先创建子类的实例this,
然后再将父类的方法添加到子类实例this上面,也就是说,ES5中,每一个实例是有自己的
this的,而到了ES6中,继承机制变成了,先创建父类的实例this,然后子类去修改父类的
this实现继承,因此要想在ES6中实现继承,需要使用super去引用父类的构造函数,返回
子类实例即 super 内部的 this 指的是 B,因此 super() 在这里相当于`A.prototype.constructor.call(this, props)`。
但是,如果不使用constructor,组件无法使用state,打印的state始终都是null,
也就是说,如果使用无state组件,可以不使用constructor,只通过props来接收值
(这个时候就建议使用无状态组件了),这种主要作用是模板,和只接收父元素的值得情况;
如果要用state,需要把this. state写到constructor里面,
(2)
state={
name:666
},
在react中,如果没有显式的去定义constructor方法,在执行的时候,constructor也会被
添加,这样一来,任何一个子组件无论有没有显式的定义,都有constructor方法,因此constructor
方法的定义并不是必须的。
注
变量不可以放空值,未定义的话赋值null
5.改值
import React from 'react'
class Class1 extends React.Component{
state={
name:666
}
fn=()=>{
this.setState({
name:this.state.name+1
})
console.log(this.state.name);
}
render(){
return (
<div>
类组件==={this.state.name}
<button onClick={this.fn}>+1</button>
</div>
)
}
}
export default Class1
注
-
不可以num++因为变量名后面++先获取后赋值,数据相当于慢一次
-
log获取到的慢一次,因为改state属于异步操作后执行
-
箭头函数里调用this指向外部环境
-
若不使用箭头函数而使用函数
方法1 <div> 类组件==={this.state.name} <button onClick={this.fn.bind(this)}>+1</button> </div> 方法2 constructor(){ super() this.fn=this.fn.bind(this) } 方法3(常用) <button onClick={()=>this.fn()}>+1</button>
6.受控组件(常用)
是什么
value值受到了react控制的表单元素
怎么做
- 根据表单元素类型获取对应的值
- 在事件处理程序修改对应的state
import React from 'react'
class Hello extends React.Component{
state={
desc:'帅锅'
}
ff=(e)=>{
this.setState({
desc:e.target.value
})
}
render(){
return (
<div>
<br/>
描述:
<textarea
name='desc'
onChange={this.ff}
value={this.state.desc}
></textarea>==={this.state.desc}
<br/>
</div>
)
}
}
export default Hello
7.非受控组件
是什么
非受控组件借助于ref,使用原生DOM的方式来获取表单元素的值
怎么用
-
调用React.createRef()方法创建一个ref -
将ref对象添加到对应文本框中 -
通过ref对象获取文本框的值并修改state中的值
import React from 'react'
class Hello extends React.Component{
state={
val2:'true'
}
txt=React.createRef()
fff=()=>{
console.log(this.txt.current.value,8);
this.setState({
val2:this.txt.current.value
})
}
render(){
return (
<div>
单身:
<input
type='text'
onChange={this.fff}
ref={this.txt}
></input>==={this.state.val2}
</div>
)
}
}
export default Hello
8.综合案例
import React from 'react'
class Hello extends React.Component {
state = {
list: [
{ id: 1, name: '水浒传' },
{ id: 2, name: '西游记' },
{ id: 3, name: '红楼梦' },
],
val: '',
vv:'添加',
setId:0,
}
Books=(e)=>{
this.setState({
val:e.target.value,
id:this.state.list.length+1
})
}
addBooks = () => {
if(this.state.vv==='编辑'){
let list = this.state.list
list[this.state.setId].name=this.state.val
this.setState({
vv:'添加',
list,
val:''
})
}else{
console.log('2');
this.state.list.push(
{name:this.state.val,
id:this.state.list.length+1
})
this.setState({
list:this.state.list
})
}
}
delBooks=(id)=>{
console.log(id);
this.setState({
list:this.state.list.filter(item=>item.id!==id)
})
}
setBooks(item,index){
this.setState({
vv:'编辑',
setId:index,
val:item.name
})
}
render() {
return (
<div>
===Todo===
<input
type="text"
value={this.state.val}
onChange={this.Books}
/>==={this.state.val}
<button onClick={this.addBooks}>{this.state.vv}</button>
<ul>
{this.state.list.map((item,index) => (
<li key={item.id}>
标号:{item.id}===书名:{item.name}====
<button onClick={()=>this.delBooks(item.id)}>删除</button>
{/* 函数的话不加括号立即执行 */}
===<button
onClick={()=>this.setBooks(item,index)}>编辑</button>
</li>
))}
</ul>
</div>
)
}
}
export default Hello
三.组件间传值
0.父
import React from 'react'
import Son2 from './props/son2'
import Son from './props/son'
class Com extends React.Component {
state={
sMsg:'1'
}
fatherFn=(msg)=>{
this.setState({
sMsg:msg
})
console.log('father',msg);
}
render() {
return <div>
<Son ff={this.fatherFn}></Son>
<Son2 f={this.state.sMsg}></Son2>
</div>
}
}
export default Com
1.父传子
src\props\son2.js
import React from 'react'
const Func = (props) => {
let fn=(i)=>{
console.log(i);
}
return <div>
<button onClick={()=>fn(props.f)}>son22</button>
<h1>{props.f}</h1>
</div>
};
export default Func
2.子传父
src\props\son.js
import React from 'react'
class Com extends React.Component {
f=()=>{
this.props.ff('1')
}
render() {
return <div>
<button onClick={this.f}>son1</button>
<button onClick={()=>this.props.ff('我传的')}>son11</button>
</div>
}
}
export default Com
3.后代传值
(1)获取react内置组件
src\context
import React from 'react'
const { Provider , Consumer } = React.creatContext()
export { Provider , Consumer }
注:不建议用export default因为{}会被解析为export会出报错eslint报错
(2)爷爷
App.js
import { Provider } from './context'
import Son from './props/son'
...
render(){
return (
<Provider value=传的值>
<Son></Son>
</Provider>
)
}
(3)儿子
import Sun from './sun'
render(){
return(
<sun></sun>
)
}
(4)孙子
import { Consumer } from './context'
...
return <Consumer>{(data)=><span>{data}</span>}</Consumer>//即可获取到爷爷传过来的值