React元素&组件
元素
React元素是普通的对象,其与浏览的的DOM元素不同,而React DOM
的作用是确保浏览器的数据内容与React元素保持一致
通常我们设置一个 id为root的div 将其内容都由React DOM
来管理,就称之为根节点
元素渲染
React元素是不可变的,当被创建后无法改变其内容和属性,我们可以通过设置不同的react元素挂载到根节点来更新界面
function tick() {
const element = (
<div>
<h1> hello lyy!</h1>
<h2> It is {new Date().toLocaleTimeString()}</h2>
</div>
)
ReactDOM.render(element, document.getElementById('root'))
}
setInterval(() => {
tick()
}, 1000);
但是我们通常在项目中只挂载一次,因此我们想要更新元素,就需要使用到有状态组件
ReactDOM为了节约性能 会比较前后元素的不同后,只会渲染改变的部分,因此对于上面的例子 即使每秒钟都创建了新的元素 也只会渲染改变的部分而不是整个页面
组件
组件是一个或者多个React元素的组合,接受任意的输入值(props)在页面上进行展示
定义组件方法:
{name: "liyuyuan"}
作为props
传给新的组件
//使用函数
function Welcome(props) {
return <h1>Hello, {props.name}</h1>
}
//使用class
class Welcome extends React.Component {
render() {
return <h1>Hello, svg, {this.props.name}</h1>
}
//设置挂载点为 Welcome 组件
ReactDOM.render(<Welcome name="liyuyuan"/>, document.getElementById('root'));
}
组件也可以作为React
元素
const element = <Welcome name="zhe shi shen me?" />
组件返回只能为一个根元素,因此需要把这几个元素用div
进行包裹
function WelcomeTest(props) {
return (
<div>
<Welcome name="zhe 第一行?" />
<Welcome name="zhe 第二行" />
<Welcome name="zhe 第三行" />
</div>
)
}
Props属性是只读的
组件不能修改自己的props
,意思是不能改变自己的输入值,当输入值相同时一定得到相同的输出结果(纯函数)
条件渲染
可以根据条件渲染不同的组件
render() {
let element
if(true) {
element = <a href="#" onClick={this.actionClick}> Click Me </a>
} else {
element = <a href="http://www.baidu.com" onClick={this.actionClick}> Click Me </a>
}
return element
}
在jsx代码中嵌入逻辑js代码和React元素 条件渲染元素
render() {
return(
<div>
{true && <h1> 条件渲染 </h1>}
</div>
)
}
条件性不渲染元素
render() {
if (true) {
return null
} else {
return (
<h1>条件渲染</h1>
)
}
}
当不渲染元素时 可以返回null
当返回null时 并不影响组件的声明周期函数
列表组件
利用js中的map函数 创建一个元素列表组件
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
//创建一个元素,需要加一个特殊的key值
<li key={number.toString()}>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
元素的key
我们在创建列表元素时, 当该元素有多个兄弟元素时,需要给元素增加标识即 key
,帮助在DOM中元素发生变化后识别哪些元素发生了变化.元素的key应该在兄弟元素间是唯一的(并不需要全局唯一,即多个非兄弟关系的元素之间key可以相同) 通常使用数据id(如果没有id就用下标index)作为元素的key
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
//在jsx代码中嵌入js表达式
function NumberList(props) {
const numbers = props.numbers;
return (<ul>
{ numbers.map((num) => (<li key={num}>
{2*num}
</li>)) }
</ul>)
}
表单
受控组件
受控组件:即将组件的每个状态改变都有与之相关的处理函数,控制其行为
Form
我们将表单改变为一个可控的组件 将值的改变包括在组件的state
中,通过state改变组件的渲染
改变submit时会自动刷新页面的行为即阻止默认行为
export default class FormElement extends React.Component {
constructor(props) {
super(props)
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({value: event.target.value})
}
handleSubmit(event) {
//阻止提交表单的默认行为
event.preventDefault();
}
render() {
return(
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange}></input>
</label>
<input type="submit" value="Submit"></input>
</form>
)
}
}
event.preventDefault(); 阻止默认行为
当一个控件中存在多个受控元素,我们可以给元素指定name
属性,让处理函数根据event.target.name
值来选择做什么
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
//利用计算属性名 来设置状态值的键
[name]: value
});
}