react组件实例对象的三大核心(state,props,refs)

组件实例对象的三大核心
一、state

class Weather extends React.Component {
  constructor(props) {
    super(props);
    // 解决demo中this指向问题
    this.test = this.this.demo.bind(this);
  }
  state = { isHort: true };

  render() {
    const { isHort } = this.state;
    return <h1 onClidk={this.test}>今天天气很{isHort ? "炎热" : "凉爽"}</h1>;
  }
  demo() {
    // demo放在哪里? —— Weather的原型对象上,拱实例使用
    // 由于demo是作为onClidk的回调,所以不是通过实例调用的,是直接调用, 类中的方法默认开启了局部的严格模式,this= undefined
    console.log(this.state.isHot);
    // 严重注意,状态(state) 不可直接更改,要借助一个内置的API去更改
    // this.state.isHot = !this.state.isHot
    // 状态(state)必须通过setState 更改,且更新是一种合并
    const isHort = this.state.isHot;
    this.setState({ isHort: !isHort });
  }
}
reactDom.render(<Weather />, document.querySelector("id"));
// 常用
class Weather extends React.Component {
  // 初始化状态
  state = { isHort: true };
  render() {
    const { isHort } = this.state;
    return <h1 onClidk={this.test}>今天天气很{isHort ? "炎热" : "凉爽"}</h1>;
  }
  // 自定义方法 —————— 要用赋值语句加箭头函数
  demo = () => {
    console.log(this.state.isHot);
    const isHort = this.state.isHot;
    this.setState({ isHort: !isHort });
  };
}
reactDom.render(<Weather />, document.querySelector("id"));

注意!!!
组件中 render 方法中的 this 为组件实例对象
组件自定义的方法中 this 为 undefined,如何解决?
a.强制绑定 this: 通过函数对象的 bind{}
b.箭头函数
状态数据,不能直接修改或更新

二、props

 // 我们只需要让 Preson 这个类 自身有 propTypes  和 defaultProps  就可以帮我们进行限制
 /*
   Person.static propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number,
    sex: PropTypes.string,
  };
  Person.static defaultProps = {
    sex: "男",
    age: 18,
  };
 
 */
class Person extends React.Component {
  // static 静态加载
  static propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number,
    sex: PropTypes.string,
  };
  static defaultProps = {
    sex: "男",
    age: 18,
  };
  constructor(props){
    // 构造器是否接受props  是否传递给super 取决于 是否希望在构造器中通过this访问props
    
    super(porps)
    consoloe.log(this.props)
  }
  render() {
    console.log(this);
    // this.props.name = 'jack'   // 此行代码会报错,因为props 是只读的
    return (
      <ul>
        <li>姓名:{this.props.name}</li>
        <li>年龄:{this.props.age}</li>
        <li>性别:{this.props.sex}</li>
      </ul>
    );
  }
}

ReactDOM.render(
  <Person name="jerry" sex="男" age={19} />,
  document.getElementById("root")
);
const p = { name: "Tom", age: 18, sex: "女" };
// ...p 在原生js中 不可以展开对象 但是可以 {...p}
// 在react 中 ...p 可以传递标签属性
ReactDOM.render(<Person {...p} />, document.getElementById("root"));
    function Person(props){
      const {name , age , sex} = props
      return (<ul>
      <li>{name}</li>
      <li>{age}</li>
      <li>{sex}</li>
      </ul>)
    }
const p = { name: "Tom", age: 18, sex: "女" };
ReactDOM.render(<Person {...p} />, document.getElementById("root"));


每个组件对象都会有 props{properties 的简写}属性
组件标签的所有属性都保存在 props 中
通过标签属性从组件外向组件内传递变化的数据
注意::: 组件内部不要修改 props 数据
对 props 中的属性值进行类型限制和必要性限制

// 注意 : 这种方式(React v15.5开始已弃用)
    Person.propTypes = {
        name : React.PropTypes.string.isRequired,
        age: React.PropTypes.number
    }

    // 第二种方式(新) 使用prop-types库进行限制(需要引入prop-types库)
    Person.propTypes = {
        name:PropTypes.string.isRequired,
        age : PropTypes.number
    }
    // 可以将对象的所有属性通过props传递
   <Person {...person}>
   // 默认值属性
   Person.defaultProps = {
       age:18,
       sex:'男'
   }
   // 组件类的构造函数
   constructor(props){
       super(props)
       console.log(props)
   }

三、refs 与事件处理
(1) 字符串形式的ref

class Demo extends React.Component {
    showData = () => {
        const { input1 } = this.refs;
        alert(input1.value);
    };
    showData2 = () => {
        const { input2 } = this.refs;
        alert(input2.value);
    };
    render() {
        return (
            <div>
                <input ref="input1" type="text" />
                <button onClick={this.showData}>点我提示</button>
                <input ref="input2" onBlur={this.showData2} type="text" />
            </div>
        );
    }
}
ReactDOM.render(<Demo />, document.getElementById('test'));

(2)回调形式的refs
每一次去更新节点的时候 ref回调函数会执行两次,第一次传入参数null,第二次传入参数DOm节点。这是因为在每次渲染时会创建一个新的函数实例,所以react会清空旧的ref并且设置新的,通过将ref的回调函数定义成class的绑定函数的方式去避免上述问题

class Demo extends React.Component {
    showData  = ()=>{
        alert(this.input.value)
    };
     showData2 = () => {
       
        alert( this.input2.value);
    };
    savainput = (c)=>{
        this.input1 = c
    }
    render() {
        // this.input= c} type="text" />  ref的回调 c 是当前input节点
        return (
            <div>
            {/* ref回调函数*/}
              {/*  this.input= c} type="text" />*/}
              {/*class的绑定函数*/}
              <input ref={this.savainput} type="text" />
                <button onClick={this.showData}>点我提示</button>
                <input  ref={c=>this.input2 = c} onBlur={this.showData2} type="text" />
            </div>
        );
    }
}
ReactDOM.render(<Demo />, document.getElementById('test'));

(3)createRef

class Demo extends React.Component {
    // React.createRef调用后可以返回一个容器,该容器存储被ref所标识的节点 该容器只能存一个
    showData  = ()=>{
        alert(this.myRef.current.value)
    };
    
    render() {
        // this.input= c} type="text" />  ref的回调 c 是当前input节点
        return (
            <div>
         
              <input ref={this.myRef} type="text" />
                <button onClick={this.showData}>点我提示</button>
            </div>
        );
    }
}
ReactDOM.render(<Demo />, document.getElementById('test'));

你可能感兴趣的:(reactjs,前端)