<script type="text/babel">
function MyComponent() {
return <h2>我是函数定义的组件(适用于简单组件的定义)</h2>
}
ReactDOM.render(<MyComponent />, document.getElementById('test'))
</script>
1.React解析了组件标签,找到了对应的组件
2.发现这个组件是一个函数定义的,随后调用该函数,生成一个虚拟dom
3.最后将虚拟dom转化成为真实dom,呈现在页面中
<script type="text/babel">
class MyComponent extends React.Component {
render() {
return <h2>我是类定义的组件适用于复杂数据类型</h2>
}
}
ReactDOM.render(<MyComponent />, document.getElementById('test'))
</script>
1.React解析了组件标签,找到了对应的组件
2.发现这个组件是一个类定义的,随后new出来一个实例对象,并通过该实例调用原型上的render方法
3.将render()返回的内容生成一个虚拟dom
4.最后将虚拟dom转化成为真实dom,呈现在页面中
组件名必须首字母大写
虚拟DOM元素只能有一个根元素
虚拟DOM元素必须有结束标签
state
是一个对象,它包含组件的数据状态,当状态变化时,会触发视图的更新。你可以理解它的作用跟 Vue
中的 data
对象类似。<script type="text/babel">
class Weather extends React.Component {
constructor() {
super()
this.state = {
isHot: false,
wind: '微风'
}
this.chang = this.chang.bind(this)
}
render() {
let { isHot, wind } = this.state
return <h2 onClick={this.chang}>今天的天气很 {isHot ? "炎热" : "凉爽"},{wind}</h2>
}hang() {
console.log(this)
this.setState({
isHot: !this.state.isHot
})
}
}
ReactDOM.render(<Weather />, document.getElementById('test'))
</script>
1.组件中render方法中的this为组件实例对象
2.组件自定义的方法中this为undefined,如何解决?
1.强制绑定this: 通过函数对象的bind()
2.箭头函数
3.状态数据,不能直接修改或更
<script type="text/babel">
class Weather extends React.Component {
state = {
isHot: false,
wind: '微风'
}
render() {
let { isHot, wind } = this.state
return <h2 onClick={this.chang}>今天的天气很 {isHot ? "炎热" : "凉爽"},{wind}</h2>
}
chang = ()=>{
this.setState({
isHot: !this.state.isHot//这里的修改是一种合并,对比属性的变化,如果有赋新值,没有则跳过
})
}
}
ReactDOM.render(<Weather />, document.getElementById('test'))
let a = new Weather()
</script>
setState(object nextState[, function callback])
不能在组件内部通过 this.state
修改状态,因为该状态会在调用 setState() 后被替换。
setState()
并不会立即改变 this.state
,而是创建一个即将处理的 state
。setState()
并不一定是同步的,为了提升性能 React
会批量执行 state
和 DOM
渲染。
setState()
总是会触发一次组件重绘,除非在 shouldComponentUpdate()
中实现了一些条件渲染逻辑。
React
中组件通过 props
属性接收外部传入的数据,这点 Vue 跟 React 是一致的组件之间的通信
。不可变的
,但是有一种情形它貌似可变,即是将父组件的 state作为子组件的 props
,当父组件的 state 改变,子组件的 props 也跟着改变,其实它仍旧遵循了这一定律:props 是不可更改的
。<script type="text/babel">
class MyComponent extends React.Component {
render() {
return (
<ul>
<li>{this.props.name}</li>
<li>{this.props.age}</li>
</ul>
);
}
}
ReactDOM.render(
<MyComponent name="Bob" age="18" />,
document.getElementById("test")
);
</script>
class MyComponent extends React.Component {
render() {
return (
<ul>
<li>{this.props.name}</li>
<li>{this.props.age}</li>
</ul>
);
}
}
// 校验类型
MyComponent.propTypes = {
name: PropTypes.string, // 这里的 PropTypes 变量是全局挂载的
age: PropTypes.number,
};
ReactDOM.render(
<MyComponent name="Bob" age={18} />,
document.getElementById("test")
);
<script type="text/babel">
class Weather extends React.Component {
constructor(props) {//是否接受,取决于是否使用外部数据
super(props)//只能上面接受了props,super()就去传递,否则后续的使用,可能就会出现问题
}
static propTypes = {
name: PropTypes.string.isRequired,//限制name为字符串类型,必填
// age: PropTypes.number,
sex: PropTypes.string,
speak: PropTypes.func
}
static defaultProps = {
sex: '男',
}
render() {
let { name, age, sex } = this.props
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
)
}
}
ReactDOM.render(<Weather name="tom" age={26} sex="女" />, document.getElementById('test'))
</script>
<script type="text/babel">
// 函数组件
function MyComponent(props) {
return (
<ul>
<li>{props.name}</li>
<li>{props.age}</li>
</ul>
);
}
// 校验类型
MyComponent.propTypes = {
name: PropTypes.string,
age: PropTypes.number,
};
ReactDOM.render(
<MyComponent name="Bob" age={18} />,document.getElementById("test")
);
</script>
字符串方式
,回调函数式
,createRef
。DOM 节点
或者在render方法
中创建的React元素
。父子组件
交互的唯一方式
。要修改一个子组件,需要通过的新的props
来重新渲染。强制修改子组件
。被修改的子组件可能是一个React组件实例
,也可能是一个DOM元素
。对于这两种情况,React
都通过 Refs
的使用提供了具体的解决方案。<script type="text/babel">
class MyComponent extends React.Component {
handleAlert = () => {
// 在 refs 中获取定义的 ref 标识
const { myInput } = this.refs;
console.log(myInput); //
alert(myInput.value);
};
render() {
return (
<div>
{/* 使用 ref="" 方式直接定义字符串标识 */}
<input ref="myInput" type="text" />
<button onClick={this.handleAlert}>alert</button>
</div>
);
}
}
ReactDOM.render(<MyComponent />, document.getElementById("test"));
</script>
<script type="text/babel">
class MyComponent extends React.Component {
handleAlert = () => {
// 直接从组件实例上获取 myInput
console.log(this.myInput); //
alert(this.myInput.value);
};
render() {
return (
<div>
{/* ref 直接定义成一个回调函数,参数就是节点本身,将它赋值给组件的一个 myInput 属性 */}
<input ref={(ele) => (this.myInput = ele)} type="text" />
<button onClick={this.handleAlert}>alert</button>
</div>
);
}
}
ReactDOM.render(<MyComponent />, document.getElementById("test"));
</script>
React官方提示:
如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
<script type="text/babel">
class MyComponent extends React.Component {
// 创建 ref
myInput = React.createRef();
handleAlert = () => {
console.log(this.myInput.current); // 这里需要注意,元素是在 current 属性上
alert(this.myInput.current.value);
};
render() {
return (
<div>
{/* 将创建好的 ref 附加到元素上 */}
<input ref={this.myInput} type="text" />
<button onClick={this.handleAlert}>alert</button>
</div>
);
}
}
ReactDOM.render(<MyComponent />, document.getElementById("test"));
</script>
上面就是使用 React.createRef() 方法创建 ref 的方式,特别需要注意的是,创建出来的 ref 的值是一个对象,我们需要的 DOM 元素是放在对象的 current 属性上,如上面的 this.myInput.current。
以上就是React面向组件编程中的一部分。希望本篇文章能够帮助到你,若有错误欢迎指出,不懂得可以评论区或者私信问我,我也会一 一解答。谢谢观看!
我的其他文章:https://blog.csdn.net/m0_60970928?type=blog