zoukankan      html  css  js  c++  java
  • react->Context笔记

    此文章想记录一下react的context的使用以便于以后的复习

    先附上我的目录

    第一步在context.js上写下这样的代码:

    context.js

    import React from 'react'
    const MyContext = React.createContext( 'defalut' )
    export default MyContext

    第二步在TodoList.js里把context.js引进来,然后再把要传给子组件用的方法和数据赋值到context.js上

    TodoList.js

      1 import React, { Component } from 'react'
      2 import TodoForm from './TodoForm'
      3 import TodoContent from './TodoContent'
      4 import MyContext from '../context' // 把context.js引进来
      5 class TodoList extends Component {
      6     constructor () {
      7         super ()
      8         this.state = {
      9             checkedAll:false,
     10             datalist: [
     11                 {
     12                     id: Date.now(),
     13                     title: "明年实现月薪过万",
     14                     done: false,
     15                     selected: false
     16                 },
     17                 {
     18                     id: Date.now() + 10,
     19                     title: "男同学变成高富帅,迎娶白富美",
     20                     done: false,
     21                     selected: false
     22                 },
     23                 {
     24                     id: Date.now() + 20,
     25                     title: "女同学变成白富美,迎娶高富帅",
     26                     done: false,
     27                     selected: false
     28                 }
     29             ]
     30         }
     31         this.addItem = this.addItem.bind( this )
     32         this.removeItem = this.removeItem.bind( this )
     33         this.completeItem = this.completeItem.bind( this )
     34         this.selecteItem = this.selecteItem.bind( this )
     35         this.selectedAll = this.selectedAll.bind( this )
     36         
     37     }
     38     addItem ( title ) { // 添加事项
     39         let datalist = this.state.datalist
     40         datalist.unshift(
     41             {
     42                 id: Date.now() + 20,
     43                 title,
     44                 done: false,
     45                 selected: false
     46             }
     47         )
     48         this.setState({ datalist })
     49     }
     50     removeItem ( id ) { // 删除事项
     51     //    let datalist = this.state.datalist.filter( item => item.id !== id )
     52        this.setState({ datalist: this.state.datalist.filter( item => item.id !== id ) })
     53     }
     54     completeItem ( id ) { // 变成完成事项
     55         let datalist = this.state.datalist.map( item => {
     56             if ( item.id === id ) {
     57                 item.done = !item.done
     58             }
     59             return item
     60         })
     61         this.setState( { datalist } )
     62     }
     63     selecteItem ( id ) {  // 改变check状态
     64        let datalist = this.state.datalist.map( item => {
     65            if ( item.id === id ) {
     66                item.selected = !item.selected
     67            }
     68            return item
     69        })
     70        this.setState( { datalist, checkedAll: datalist.every( item => item.selected ) } )
     71     }  
     72     selectedAll () {      // 全选
     73         let checkedAll = !this.state.checkedAll
     74         let datalist = this.state.datalist.map( item => {
     75             item.selected = checkedAll
     76             return item
     77         })
     78         this.setState( { checkedAll,datalist } )
     79     }
     80     render () {
     81         let {selecteItem,removeItem,completeItem,addItem} = this
     82         let { datalist, checkedAll } = this.state
     83         return (
     84             <div>
     85                <MyContext.Provider value = { { selecteItem,removeItem,completeItem,addItem } }>  // 将需要的方法传到MyContext里传递,那么就不用一个个传递到子组件这么麻烦了,但是使用context会使组件复用性变差
     86                     <TodoForm 
     87                     addItem = { addItem }
     88                     ></TodoForm>
     89                     <TodoContent
     90                     selectedAll = { this.selectedAll }
     91                     datalist = { datalist }
     92                     checkedAll = { checkedAll }
     93                     >
     94                     </TodoContent>
     95                 </MyContext.Provider>
     96                 
     97             </div>
     98         )
     99     }
    100 }
    101 export default TodoList

    TodoList的子组件有TodoContent.js和TodoForm.js

    TodoContent.js

     1 import React from 'react'
     2 import PropTypes from 'prop-types'
     3 import TodoItem from './TodoItem'
     4 function TodoContent ( props ) {
     5     console.log( 'TodoContent.props', props )
     6     return (
     7         <>
     8             <table>
     9                 <thead>
    10                     <tr>
    11                         <th><input type = 'checkbox' checked = { props.checkedAll } onChange = { props.selectedAll } />全选</th>
    12                         <th>#</th>
    13                         <th>待办事项</th>
    14                         <th>是否完成</th>
    15                         <th>操作</th>
    16                     </tr>
    17                 </thead>
    18                 <tbody>
    19                     {
    20                         props.datalist.map( (item,idx) => {
    21                             return (
    22                                 <TodoItem
    23                                 key = { item.id }
    24                                 data = { item }
    25                                 idx = { idx }
    26                                 >
    27                                 </TodoItem>
    28                             )
    29                         } )
    30                     }
    31                 </tbody>
    32             </table>
    33             <div>总数:{props.datalist.length},完成:{props.datalist.filter( item => item.done).length},未完成:{props.datalist.filter( item => !item.done).length}</div>
    34         </>
    35     )
    36 }
    37 TodoContent.propTypes = {
    38     datalist: PropTypes.array.isRequired
    39 }
    40 TodoContent.defaultProps = {
    41     datalist: []
    42 }
    43 export default TodoContent

    TodoItem.js(TodoContent.js的子组件)

     1 import React from 'react'
     2 import MyContext from '../context'
     3 import Button from './TodoButton'
     4 function TodoItem({ data, idx }) {
     5     return (
     6         <MyContext.Consumer> // 使用此标签来把context的值传进来,那么函数组件就可以使用这样的方式来接受context父组件传过来的方法了,相当于vue的bus总线一样,只不过react的写法多端
     7             {
     8                 value => {
     9                     let { selecteItem,removeItem,completeItem } = value
    10                     return (
    11                         <tr>
    12                             <td>
    13                                 <input type='checkbox' checked={data.selected} onChange={selecteItem.bind(null, data.id)} />
    14                             </td>
    15                             <td>{idx + 1}</td>
    16                             <td>{data.title}</td>
    17                             <td>{data.done ? '是' : '否'}</td>
    18                             <td>
    19                                 <Button onClick={completeItem.bind(null, data.id)}>完成</Button>
    20                                 <Button onClick={removeItem.bind(null, data.id)}>删除</Button>
    21                             </td>
    22                         </tr>
    23                         )
    24                     }
    25                 }
    26         </MyContext.Consumer>
    27     )
    28 }
    29 export default TodoItem

    TodoButton.js(TodoItem.js的子组件)

     能够获取到父组件传进来的文字和事件,

     1 import React from 'react'
     2 const TodoButton = props => {
     3     // console.log('Button:',props.children,React.Children, 'props->',props,'React->',React);
     4     React.Children.forEach(props.children,function(item,idx){
     5         // console.log(item,idx,'BUTTON出来的')
     6     })
     7     return (
     8         <button onClick = { props.onClick }>{ props.children }</button>
     9     )
    10 }
    11 export default TodoButton

    TodoForm.js(TodoList的子组件)

    TodoForm.js是类组件,有自己的状态也有this,所以可以这么写,通过TodoForm.contextType = MyContext,就能在类组件使用this.context.xxx()使用context的方法了

     1 import React, { Component } from 'react'
     2 import MyContext from '../context'
     3 export default class TodoForm extends Component {
     4     constructor(props) {
     5         super(props)
     6         this.state = {
     7             title: ''
     8         }
     9         this.changeTitle = this.changeTitle.bind( this )
    10         this.additem = this.additem.bind( this )
    11         this.enter = this.enter.bind( this )
    12     }
    13     changeTitle(event) {
    14         this.setState({ title: event.target.value })
    15     }
    16     additem() {
    17         let  title  = this.state.title
    18         if ( String( title ).trim() === "" ) {
    19             alert( '事项名称必填!' )
    20             return
    21         }
    22         this.context.addItem( title )
    23         console.log('title->', title)
    24         this.setState({ title: '' })
    25         this.eles.focus()
    26     }
    27     enter(event) {
    28         if (event.which === 13) {
    29             this.additem()
    30         }
    31     }
    32     render() {
    33         return (
    34             <div>
    35                 <input
    36                     type='text'
    37                     ref = { ele => this.eles = ele}
    38                     value = { this.state.title }
    39                     onChange = { this.changeTitle }
    40                     onKeyPress = { this.enter }
    41                 />
    42                 <button onClick={this.additem}>添加</button>
    43             </div>
    44         )
    45     }
    46 }
    47 TodoForm.contextType = MyContext

    函数组件和类组件有所区别

    因为class组件有this,所以可以使用this.context,而this.context是react里面自带,可以来获取context的值

    但是函数组件没有this,只能使用Consumer来获取context的值,但是Consumer是class类组件和函数组件都能用的

    所以使用context的方式也有所区别。

    如果我哪里不对,希望大家纠正

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    机器学习-TensorFlow2.0安装简易教程
    14 深度学习-卷积
    用python画出你的童年回忆
    13-垃圾邮件分类2
    事后诸葛亮分析
    团队项目四:项目冲刺之日志集合贴
    第 1 篇 Scrum 冲刺博客
    团队作业1——团队展示&选题
    结对作业:四则运算(Java+JavaFX)
    JavaGUI之Swing简单入门示例
  • 原文地址:https://www.cnblogs.com/jackal1234/p/13378780.html
Copyright © 2011-2022 走看看