state 为状态
通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
状态必须通过setState进行更新, 且更新是一种合并 不是替换
//1.创建类式组件
class Mycomponent extends React.Component{
// 构造器 调用了一次
constructor(props){
super(props);
// 初始化状态
this.state = {isHot:false,wind:'微风'}
//解决 change中this指向问题
this.change = this.change.bind(this)
}
// render 调用 1+n次 每次修改状态都需要调用
render(){
console.log(this);
return <h2 onClick={this.change}>今天天气很{this.state.isHot ? '炎热' : '凉爽'},{this.state.wind}</h2>
}
change(){
//change 放在 Mycomponent 的原型对象上 供实例使用
// 由于 change 是作为 onClick的回调 所以不是通过实例调用的 是直接调用
// 类中的方法默认开启了局部的严格模式,所以change 中的this为undefined
const isHot = this.state.isHot
// 状态(state)不可直接更改!
//this.state.isHot =!isHot
//状态必须通过setState进行更新, 且更新是一种合并 不是替换
this.setState({isHot:!isHot})
}
}
//2.渲染组件到页面
ReactDOM.render(<Mycomponent/>,document.getElementById('test'))
//1.创建类式组件
class Mycomponent extends React.Component{
// 初始化状态
state = {isHot:false,wind:'微风'}
render(){
console.log(this);
return <h2 onClick={this.change}>今天天气很{this.state.isHot ? '炎热' : '凉爽'},{this.state.wind}</h2>
}
// 自定义方法 用赋值语句的形式 + 箭头函数
change = ()=>{
const isHot = this.state.isHot
this.setState({isHot:!isHot})
}
}
//2.渲染组件到页面
ReactDOM.render(<Mycomponent/>,document.getElementById('test'))
//创建组件
class Person extends React.Component{
render(){
const{name,age,sex} = this.props
return(
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>age: {age+1}</li>
</ul>
)
}
}
//渲染组件到页面
const p = {name:'tom', sex:'男', age:18}
ReactDOM.render(<Person {...p} />,document.getElementById('test'))
//创建组件
class Person extends React.Component{
render(){
const{name,age,sex} = this.props
// props 是只读的 不能修改
return(
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>age: {age+1}</li>
</ul>
)
}
}
//对标签属性进行类型 必要性的限制
Person.propTypes ={
name:PropTypes.string.isRequired, //name必传 且为字符串
sex:PropTypes.string,
age:PropTypes.number,
speak:PropTypes.func, //限制 speak 为函数
}
//指定默认标签属性值
Person.defaultProps ={
sex:'男', //默认值
age:18
}
//渲染组件到页面
const p = {name:'tom', sex:'男', age:18}
ReactDOM.render(<Person {...p} speak={speak} />,document.getElementById('test'))
function speak(){
console.log('i can speak');
}
//创建组件
class Person extends React.Component{
// constructor(props){
// // 构造器是否接收 props 是否传递给super 取决于 在构造器中是否 通过this访问props
// console.log(props);
// super(props);
// }
//对标签属性进行类型 必要性的限制
static propTypes ={
name:PropTypes.string.isRequired, //name必传 且为字符串
sex:PropTypes.string,
age:PropTypes.number,
speak:PropTypes.func, //限制 speak 为函数
}
//指定默认标签属性值
static defaultProps ={
sex:'男', //默认值
age:18
}
render(){
const{name,age,sex} = this.props
// props 是只读的 不能修改
return(
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>age: {age+1}</li>
</ul>
)
}
}
//渲染组件到页面
const p = {name:'tom', sex:'男', age:18}
ReactDOM.render(<Person {...p} speak={speak} />,document.getElementById('test'))
function speak(){
console.log('i can speak');
}
//创建 函数式组件
function Person(props){
const{name,age,sex} = props
console.log(props);
return(
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>age: {age+1}</li>
</ul>
)
}
//对标签属性进行类型 必要性的限制
Person.propTypes ={
name:PropTypes.string.isRequired, //name必传 且为字符串
sex:PropTypes.string,
age:PropTypes.number,
speak:PropTypes.func, //限制 speak 为函数
}
//指定默认标签属性值
Person.defaultProps ={
sex:'男', //默认值
age:18
}
//渲染组件到页面
const p = {name:'tom', sex:'男', age:20}
ReactDOM.render(<Person {...p} speak={speak} />,document.getElementById('test'))
function speak(){
console.log('i can speak');
}
简单 但是会出现bug 不推荐使用 之后可能会移除
// 1创建组件
class Demo extends React.Component{
render(){
return(
<div>
<input type="text" ref='input1' placeholder='点击按钮提示数据'/>
<button onClick={this.showData} > button</button>
<input type="text" ref='input2' onBlur={this.showData2} placeholder='失去焦点提示数据'/>
</div>
)
}
// 展示数据1
showData = ()=>{
const {input1} = this.refs
alert(input1.value)
}
// 展示数据2
showData2 = ()=>{
const {input2} = this.refs
alert(input2.value)
}
}
// 渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'))
常用 用的较多
render(){
return(
<div>
<input type="text" ref={c => this.input1 = c} placeholder='点击按钮提示数据'/>
<button onClick={this.showData} > button</button>
<input type="text" ref={c => this.input2 = c} onBlur={this.showData2} placeholder='失去焦点提示数据'/>
</div>
)
}
// 展示数据1
showData = ()=>{
alert(this.input1.value)
console.log(this);
}
// 展示数据2
showData2 = ()=>{
const {input2} = this
alert(input2.value)
}
}
// 渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'))
解决ref中回调函数 执行两次的问题 可以忽视这个问题
// 1创建组件
class Demo extends React.Component{
state = {isHot:false}
saveInput = (c)=>{
this.input1 =c;
console.log(c);
}
render(){
const {isHot} =this.state
return(
<div>
<h2>今天天气很{isHot ? '炎热':'凉爽'}</h2><button onClick={this.change} > 改变天气</button>
<br/><br/>
{/* {this.input1 = currentNode;console.log('repeat');}} /> */}
<input type="text" ref={this.saveInput}/>
<button onClick={this.showData} > button</button>
</div>
)
}
showData = ()=>{
alert(this.input1.value)
// this.setState({(this.state.isHot)=!this.state.isHot})
}
change =()=>{
const isHot = this.state.isHot
this.setState({isHot:!isHot})
}
}
// 渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'))
官网最推荐的方法 但是每建一个 ref只能供一个地方使用 需要构建多个 ref
// 1创建组件
class Demo extends React.Component{
myRef = React.createRef()
myRef2 = React.createRef()
/*
React.createRef 调用后可以返回一个容器, 该容器可以存储被ref所标识的节点,该容器是 '专人专用的'
*/
render(){
return(
<div>
<input type="text" ref={this.myRef} placeholder='点击按钮提示数据'/>
<button onClick={this.showData} > button</button>
<input type="text" ref={this.myRef2} onBlur={this.showData2} placeholder='失去焦点提示数据'/>
</div>
)
}
// 展示数据1
showData = ()=>{
alert(this.myRef.current.value);
}
// 展示数据2
showData2 = ()=>{
alert(this.myRef2.current.value);
}
}
// 渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'))```