React组件及应用

React组件名首字母必须为大写

一、组件类型

(一)函数组件

  • 函数组件(无状态组件,UI组件):
    是一个纯函数,只用组件展示,组件只负责根据外部传入的 props 来展示,书写更简洁,执行效率更高(推荐)
    默认没有this
>例子:
function Home(){
        return(
               < div></ div>
        )
}
函数内必须要有return

(二)类组件

  • 类组件(状态组件)
    (状态就是一些可变的数据,当数据改变,就会自动刷新组件:重新执行一遍render)
    类组件有更丰富的特性,如:state 状态、生命周期、this 等
>例子:
class Nav extends React.Component{
        render(){
                   return (
                           < div></ div>
                   )
          }
}
必须继承自React.Component
必须包含render(){}方法
  • React 类组件拥有自己的状态 state,state 状态改变时自动刷新组件(执行组件中的 render 方法)
>例子:
class Nav extends React.Component{
      constructor() {
                super(); // 调用super后才能使用this
                this.state = { }
       }
        render(){
                   return (
                           < div></ div>
                   )
          }
}
  • 获取:this.state.xxx
  • 修改: this.setState()
    修改state的原则:创建一个新的数据并覆盖它

this.setState({
datalist:newData
})

  • 默认只有construtor、render、生命周期函数中可以直接使用this,自定义的函数需要手动绑定(下面会进行优化)
> 例子:
class Nav extends React.Component{
      constructor() {
                super(); // 调用super后才能使用this
                this.state = { }

         // 给自定义函数绑定this
         this.addItem = this.addItem.bind(this);
       }
    //自定义方法
    addItem(text){
                const {datalist} = this.state;
                this.setState({
                    datalist:newData
                })
            }
        render(){
                   return (
                           <div>
                                  <TodoForm addItem={this.addItem} />
                           </div>
                   )
          }}

(三)受控组件与非受控组件

  • 受控组件:表单元素的值与组件的state进行绑定
  • 非受控组件:传统节点操作

二、组件通讯

  • props:类组件与函数组件都适用

函数组件:通过函数的第一个参数访问|
类组件:通过this.props访问
(类组件中的 constructor的第一个参数也是Props : constructor(props) {})

(一)父子通讯:props

1、父传子:props

(1)父组件操作:给子组件定义属性并传递数据

例子:
function TodoList() {
      let datalist = [
         { id: 1,
            text: "早点睡觉",
            done: false,
            date: new Date()
         },
      ]
         return (
            <div>
               <TodoContent datalist={datalist} />
               <TodoForm />
            </div>
         )
      }

(2)子组件操作

  • 函数组件:函数的第一个参数为props
例子:
function TodoContent(props) {
         return (
                  { props.datalist.map((item) => {
                        return <TodoItem item={item} />
                     })
                  }
         )
 }
  • 类组件:this.props
例子:
class TodoForm extends React.Component{
      constructor(props) {
                super(); // 调用super后才能使用this
                this.state = { }
       }
         submitItem() {
            if (this.state.text) {  // 对文本框有无值进行判断
               this.props.addItem(this.state.text); //传输文本框中的值
               this.setState({
                  text: '', //清空文本框
               })
            } else {}
        render(){
                   return (
                           <div>
                                 <button onClick={this.submitItem}>确定</button>
                           </div>
                   )
          }
}
2、子传父:props(把父组件的方法通过props传递到子组件中执行)

(1)父组件操作:给子组件定义属性并传递方法

例子:
function TodoList() {
      let datalist = [
         { id: 1,
            text: "早点睡觉",
            done: false,
            date: new Date()
         },
      ]
          removeItem(id) {}  //方法
         return (
            <div>
               <TodoContent  removeItem={this.removeItem}  />
            </div>
         )
      }

(2)子组件操作:执行传入的方法并传递数据

例子:
function TodoItem({ item, removeItem}) {
         return (
            <tr>
               <td>
                  <button onClick={removeItem.bind(null, item.id)}>删除</button>
               </td>
            </tr>
         )
      }

(二)兄弟组件通讯:状态提升

  • 把状态(数据)放到两个组件共同的父级

(三)多层次组件通讯

1、props 逐层传递(不推荐)
  • 从上到下,所有的组件都要帮助传递这个 props 到目标位置
  • 缺点:操作繁琐、难以维护
2、context 组件共享

所谓 context,就是上下文环境,某个组件只要往自己的 context 里面放了某些状态,这个组件之下的所有子组件都能直接访问这个状态,实现步骤如下:

(1)第一步:创建 Context:

let defaultValue = { username: "laoxie" };
**let MyContext = React.createContext(defaultValue);**
MyContext.Provider,如父组件没有共享数据,子组件获取时得到初始化数据

(2)第二步:父组件共享数据( Provider)

  • 父组件往Context中存入数据并提供给它的子组件使用

  • let data = {username:‘jingjing’}
    <MyContext.Provider value={data} >
    < App/>
    </MyContext.Provider>

  • 组件App下的所有子组件都能获取到data数据,如父组件未设置 Provider,子组件接收时得到 defaultValue 的值

(3)第三步:子组件接收数据

  • Consumer
<MyContext.Consumer>
  {
          (value) => {
              return(
                      //各个子组件跟数据
               )
             // 回调函数中获取value值
          }
   }
</MyContext.Consumer>
  • ContextType
只适用于类组件,需要给类组件添加一个静态属性
例子:
class TodoForm extends Reaact.Component{
        //this.context
}
TodoForm.contextType = MyContext
只适用于类组件,通过this.context获取
SubComponent.contextType = MyContext;
this.context.username; //jingjing
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四秋的夜猫子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值