React入门

初学注意的问题:
  • 在JSX中只能有一个根标签
  • index.css 是全局的样式
  • APP.css 是组件的样式
  • state用来改变值得状态
  • 使用方法时在方法名后面加上()时方法会自动调用
  • react中的this就是指向当前的类

=============================================

组件通信(属性传值)

组件:App.js

import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello</h1>
        <Person name="山川川1号" count="10"/>
        <Person name="山川川2号" count="20"/>

        <Person name="山川川3号" count="30">山川川在学习React!</Person>
      </div>
    )
  }
}

export default App;

组件:Person.js

import React from 'react';

const person = ( props ) => {
  // props 是这里的形参也可以是其他名字,但一般经常使用props 更好的知道我们接收的是一个属性
  return (
    <div>
      <p>大家好,我是{props.name};我已经有{props.count}个作品</p>

      {/* 拿到props 下面的子元素 */}
      <p>{props.children}</p>
    </div>
  )
}

export default person;
	 {/* 传递参数有两种方法 ,建议使用bind*/}
	<button onClick={() => this.switchNameHandler("米修")}>更改状态值</button>
	<button onClick={this.switchNameHandler.bind(this,"missyou")}>更改状态值</button>
state状态的使用
import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state不能在Person.js组件使用,因为 state 只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {name:"川川4",count:40},
      {name:"川川5",count:50},
      {name:"川川6",count:60},
    ],
    otherState:"anything"
  }

  // 定义方法
  switchNameHandle = () => {
    // 在ES6 函数中this就是指向当前的类
    // 更改状态时需要用到 setState()方法
    // 在这里只是更改persons里面的值
    this.setState({
      persons:[
        {name:"山川川1",count:10},
        {name:"山川川2",count:20},
        {name:"山川川3",count:30},
      ],
    })
  }

  render() {
    return (
      <div className="App">
        <h1>Hello</h1>

        {/* 
          这里的this.switchNameHandle 加上括号后会自动执行函数,正常不会加括号;
          如果传对应的参数时会加上括号
          */}
         // 点击事件,执行switchNameHandle方法
        <button onClick={this.switchNameHandle}>更改状态值</button>

        <Person 
          name={this.state.persons[0].name} 
          count={this.state.persons[0].count}/>
        <Person 
          name={this.state.persons[1].name}
          count={this.state.persons[1].count}/>

        <Person 
          name={this.state.persons[2].name}
          count={this.state.persons[2].count}>山川川在学习React!</Person>
      </div>
    )
  }
}

export default App;

属性传值(传事件)
  • 给事件传递参数
import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {name:"川川4",count:40},
      {name:"川川5",count:50},
      {name:"川川6",count:60},
    ],
    otherState:"anything"
  }

  // 定义方法
  switchNameHandler = (newName) => {
    // 在ES6 函数中this就是指向当前的类
    // 更改状态时需要用到 setState()方法
    // 在这里只是更改persons里面的值
    this.setState({
      persons:[
        {name:newName,count:10},
        {name:"山川川2",count:20},
        {name:"山川川3",count:30},
      ],
    })
  }

  render() {
    return (
      <div className="App">
        <h1>Hello</h1>

        {/* 
          这里的this.switchNameHandle 加上括号后会自动执行函数,正常不会加括号;
          如果传对应的参数时会加上括号
          */}
        {/* 传参 */}
        {/* 1.使用ES6 箭头函数的方法 */}
        {/* <button onClick={() => this.switchNameHandler("米修")}>更改状态值</button> */}
        {/* 2. 使用bind方法    一般传参使用bind*/}
        {/* bind(当前指向对象this,对应的名字) */}
        <button onClick={this.switchNameHandler.bind(this,"山川川,哈哈哈")}>更改状态值</button>
        
      </div>
    )
  }
}

export default App;

  • 如何使用属性传值传递一个函数

组件:App.js

import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {name:"川川4",count:40},
      {name:"川川5",count:50},
      {name:"川川6",count:60},
    ],
    otherState:"anything"
  }

  // 定义方法
  switchNameHandler = (newName) => {
    // 在ES6 函数中this就是指向当前的类
    // 更改状态时需要用到 setState()方法
    // 在这里只是更改persons里面的值
    this.setState({
      persons:[
        {name:newName,count:10},
        {name:"山川川2",count:20},
        {name:"山川川3",count:30},
      ],
    })
  }

  render() {
    return (
      <div className="App">
        <h1>Hello</h1>

        {/* 使用属性传递函数 */}
        <Person 
          myclick={this.switchNameHandler.bind(this,"山川川,真帅")}
          name={this.state.persons[1].name}
          count={this.state.persons[1].count}/>
          
      </div>
    )
  }
}

export default App;

组件:Person.js

import React from 'react';

const person = ( props ) => {
  // props 是这里的形参也可以是其他名字,但一般经常使用props 更好的知道我们接收的是一个属性
  return (
    <div>
   	  {/* 这里接收myclick属性,所以点击这句会执行App.js中switchNameHandler方法 */}
      <p onClick={props.myclick}>大家好,我是{props.name};我已经有{props.count}个作品</p>
    </div>
  )
}

export default person;
双向数据绑定

App.js

import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {name:"川川4",count:40},
      {name:"川川5",count:50},
      {name:"川川6",count:60},
    ],
    otherState:"anything"
  }

  // 定义方法
  nameChangeHandle = (event) => {
    this.setState({
      persons:[
        {name:event.target.value,count:10},
        {name:"山川川2",count:20},
        {name:"山川川3",count:30},
      ],
    })
  }

  render() {
    return (
      <div className="App">
        <h1>Hello</h1>

		{/* 双向数据绑定 */}
        <Person 
          changed={this.nameChangeHandle}
          name={this.state.persons[0].name} 
          count={this.state.persons[0].count}/>
      
      </div>
    )
  }
}

export default App;

Person.js

import React from 'react';

const person = ( props ) => {
  // props 是这里的形参也可以是其他名字,但一般经常使用props 更好的知道我们接收的是一个属性
  return (
    <div>
    
      {/* 双向数据绑定 ,  这里需要使用defaultValue否则会报错*/}
      <input type="text" onChange={props.changed} defaultValue={props.name}/>
      
    </div>
  )
}

export default person;
组件样式

1.直接引入样式
import './Person.css';

2.行间样式

import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {

  render() {
  	// 定义样式
    const style = {
      backgroundColor: 'white',
      font: 'inherit',
      border: '1px solid blue',
      padding: '8px',
      cursor: 'pointer',
    };

    return (
      <div className="App">
        <h1>Hello</h1>
		{/* 使用样式 */}
        <button style={style} onClick={this.switchNameHandler.bind(this,"山川川,哈哈哈")}>更改状态值</button>
      
      </div>
    )
  }
}

export default App;

使用分支if
import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {name:"川川4",count:40},
      {name:"川川5",count:50},
      {name:"川川6",count:60},
    ],
    otherState:"anything",
    showPersons:false,  // 定义一个状态
  }

  togglePersonHandle = () => {
    const doesShow = this.state.showPersons;
    this.setState({showPersons:!doesShow})
  }

  render() {
   	// 在render()里面定义
    let persons = null;
    if (this.state.showPersons){
      persons = (
        <div>
            <Person 
              changed={this.nameChangeHandle}
              name={this.state.persons[0].name} 
              count={this.state.persons[0].count}/>
            {/* 使用属性传递一个函数 */}
            <Person 
              myclick={this.switchNameHandler.bind(this,"山川川,真帅")}
              name={this.state.persons[1].name}
              count={this.state.persons[1].count}/>

            <Person 
              name={this.state.persons[2].name}
              count={this.state.persons[2].count}>山川川在学习React!</Person>
          </div> 
      )
    }

    return (
      <div className="App">
        <h1>Hello</h1>
        
        <button style={style} onClick={this.togglePersonHandle}>内容切换</button>
        {/* 这里只return 重要的东西,代码定义到外部 ,在这里使用persons*/}
        {persons}
       
      </div>
    )
  }
}

export default App;

使用循环并实现删除和修改
import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {id:1,name:"川川4",count:40},
      {id:2,name:"川川5",count:50},
      {id:3,name:"川川6",count:60},
    ],
    otherState:"anything",
    showPersons:false,
  }

  // 定义方法
  switchNameHandler = (newName) => {
    // 在ES6 函数中this就是指向当前的类
    // 更改状态时需要用到 setState()方法
    // 在这里只是更改persons里面的值
    this.setState({
      persons:[
        {id:1,name:newName,count:10},
        {id:2,name:"山川川2",count:20},
        {id:3,name:"山川川3",count:30},
      ],
    })
  }
  // 修改
  nameChangeHandle = (event,id) => {
    /* 
      拿到id就可以查找到更改哪一个对象的值
    */
    // 1.找到index
    const personIndex = this.state.persons.findIndex(p => {
      return p.id === id;
    }) 
    // 2.在整个数组找到当前对象
    const person = {
      ...this.state.persons[personIndex]
    }
    // 3.给当前对象的name进行赋值
    person.name = event.target.value;
    // 4.找到原型的数组
    const persons = [...this.state.persons];
    // 5.找到原型数组单独的,把修改的赋给它
    persons[personIndex] = person;

    this.setState({
      persons:persons
    })
  }
	
  togglePersonHandle = () => {
    const doesShow = this.state.showPersons;
    this.setState({showPersons:!doesShow})
  }

  deletePersonHandler = (personIndex) => {
    // const persons = this.state.persons;
    const persons = [...this.state.persons]
    persons.splice(personIndex,1);
    this.setState({
      persons:persons
    })
  }

  render() {
    // 定义样式
    const style = {
      backgroundColor: 'white',
      font: 'inherit',
      border: '1px solid blue',
      padding: '8px',
      cursor: 'pointer',
    };

    let persons = null;
    if (this.state.showPersons){
      persons = (
        <div>
            {
              // 循环
              this.state.persons.map((person,index) => {
                return <Person 
                  changed={(event) => this.nameChangeHandle(event,person.id)}
                  myclick={() => this.deletePersonHandler(index)}
                  key={person.id}
                  name={person.name} 
                  count={person.count}/>
              })
            }
          </div> 
      )
    }

    return (
      <div className="App">
        <h1>Hello</h1>

        
        <button style={style} onClick={this.togglePersonHandle}>内容切换</button>
        
        {persons}
       
      </div>
    )
  }
}

export default App;

动态修改样式和添加类名
import React ,{Component}from 'react';
import './App.css';
import Person from './Person/Person';


/* 
  state 不能在Person.js组件使用,因为state只能在类中使用而且类也要继承于component;
  Person.js只是一个函数
*/

class App extends Component {
  /* 
    state: 用于改变组件内容状态的值(动态)
    props: 用于组件通信进行传值
  */
  // state状态
  state = {
    persons:[
      {id:1,name:"川川4",count:40},
      {id:2,name:"川川5",count:50},
      {id:3,name:"川川6",count:60},
    ],
    otherState:"anything",
    showPersons:false,
  }

  // 定义方法
  switchNameHandler = (newName) => {
    // 在ES6 函数中this就是指向当前的类
    // 更改状态时需要用到 setState()方法
    // 在这里只是更改persons里面的值
    this.setState({
      persons:[
        {id:1,name:newName,count:10},
        {id:2,name:"山川川2",count:20},
        {id:3,name:"山川川3",count:30},
      ],
    })
  }

  nameChangeHandle = (event,id) => {
    /* 
      拿到id就可以查找到更改哪一个对象的值
    */
    // 1.找到index
    const personIndex = this.state.persons.findIndex(p => {
      return p.id === id;
    }) 
    // 2.在整个数组找到当前对象
    const person = {
      ...this.state.persons[personIndex]
    }
    // 3.给当前对象的name进行赋值
    person.name = event.target.value;
    // 4.找到原型的数组
    const persons = [...this.state.persons];
    // 5.找到原型数组单独的,把修改的赋给它
    persons[personIndex] = person;

    this.setState({
      persons:persons
    })
  }

  togglePersonHandle = () => {
    const doesShow = this.state.showPersons;
    this.setState({showPersons:!doesShow})
  }

  deletePersonHandler = (personIndex) => {
    // const persons = this.state.persons;
    const persons = [...this.state.persons]
    persons.splice(personIndex,1);
    this.setState({
      persons:persons
    })
  }

  render() {
    // 定义样式
    const style = {
      backgroundColor: 'green',
      color: 'white',
      font: 'inherit',
      border: '1px solid blue',
      padding: '8px',
      cursor: 'pointer',
    };

    let persons = null;
    if (this.state.showPersons){
      persons = (
        <div>
            {
              // 循环
              this.state.persons.map((person,index) => {
                return <Person 
                  changed={(event) => this.nameChangeHandle(event,person.id)}
                  myclick={() => this.deletePersonHandler(index)}
                  key={person.id}
                  name={person.name} 
                  count={person.count}/>
              })
            }
          </div> 
      )
      // ==========================当showPersons 为true 按钮的颜色会变红=========
      // 当showPersons 为true 按钮的颜色会变红
      style.backgroundColor = 'red';
    }
	// ==================动态添加类名=================================
    // const classes = ["red","bold"].join(" ") // class ="red bold"
    // 动态添加类名
    const classes = [];

    if(this.state.persons.length <= 2){
      classes.push("red"); 
    }
    if(this.state.persons.length <= 1){
      classes.push("bold"); 
    }

    return (
      <div className="App">
        <h1>Hello</h1>
        <p className={classes.join(" ")}>React,APP</p>
        
        <button style={style} onClick={this.togglePersonHandle}>内容切换</button>
        
        {persons}
       
      </div>
    )
  }
}

export default App;

this.state 和 this.props
总结:由于this.props和this.state都用于描述组件的特性,可能会产生混淆;简单的区分方法:
this.props表示那些本组件无法改变的特性,而this.state是会随着用户互动而产生变化的特性。
有状态组件和无状态组件的区别
  • 有状态组件
    1、可以拥有状态
    2、拥有生命周期
    3、可以通过this来接受状态和属性 this.state.AA this.props.AA
    4、只有在需要管理状态,或者需要使用生命周期时在用
class AA extends component{ }
  • 无状态组件
    1、不可以拥有状态
    2、不拥有生命周期
    3、可以通过属性实现数据传递 props.BB
const BB = (props) => { }
React生命周期钩子函数(有状态)
  • constructor()
    调用父级
    super(props)
    设置状态state

componentWillReceiveProps()

componentWillUpadate

componentDidCatch

componentWillUnmount()

  • componentWillMount()
    修改状态

shouldComponentUpdate

componentDidUpdate

  • componentDidMount()
    组件更新完毕
    不要更新状态

  • render()
    创建虚拟DOM
    更新DOM

constructor() =>componentWillMount() => render() =>componentDidMount()

生命周期钩子函数(更新)

componentWillReceiveProps(nextProps)
组件发生改变时触发

shouldComponentUpdate(nxPro,nxSta)
控件组件是否重新渲染

componentWillUpadate(nxPro,nxSta)
进入重新渲染流程

render()

更新与当前相关的子组件

componentDidUpdate(prevProps,prevState)
组件渲染完毕

========================================================================

后期继续更新整理

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值