组件实例对象的三大核心
一、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'));