这篇文章讲了 React 的基础知识,从 JSX 语法到面向组件编程:组件的属性 state,props,refs等属性 这是初学者写下的笔记,如有错误,欢迎指正!
React:JavaScript库 (和 jQuery 一样是个库)和 Vue 一样都尽量减少 DOM 的操作Facebook 出品的前端框架How would you React if I said I love Vue?
刚上来的时候就给我来了一个报错,弄得我很懵,其实是内嵌 script 中 type 属性 应该为 type="text/babel" 否则会报一个出现意外的小于号的错(也就是无法解析 script 里面写的其他标签)
react.js:React 的核心库
react-dom.js:提供操作 DOM 的 react 扩展库
babel.min.js:解析 jsx => js代码 (将 ES6 语法转换成 ES5)
大写转换成小写:.toLowerCase() 小写转换成大写:.toUpperCase()
debugger 关键字:相当于在书写处添加了一个断点全称 JavaScript XML
和 XML 一样都可以自定义标签 (之后叫组件标签)
babel.js 将 JSX 代码转换成纯 js 代码
假如有可能出现嵌套的 HTML 结构那么最好用括号括起来
如果我想用 li 渲染整个列表,那么我可以这么做:
let names = ['jquery', 'react', 'vue', 'angular']; // 例如: const ul = (<ul> {names.map((name,index)=>{return <li key={index}>{name}</li>})} </ul>) // 渲染到页面 ReactDOM.render(ul, document.querySelector('.test'));这就是虚拟 DOM 吗,我开始的时候想遍历整个列表,然后把他们边包裹成 li 边放到创建好的 ul 里面去,结果他不是在原来的 li 后面接着添加,而是直接覆盖掉前一个,又费事有没达到效果,看了老师的操作我想说还可以这么弄
和 Vue 小程序 一样,React 强制要求循环需要一个 key 属性来确保这个属性是唯一的注意:vscode 自动生成的 input 标签里面是没有终止符号 / 的,但是在 JSX 里面没有终止符号就会报错
在使用的时候经常会出现大组件套小组件的情况,这时就需要组件的嵌套
实例:要实现一个 todo list 页面,需要一个 App 大组件,里面嵌套两个小组件 MyInput 和 MyList 组件分别进行输入和显示
这里面的一个问题就是 MyInput 组件获取到用户输入之后如何把内容给 MyList 组件
这里我们把信息储存在他们的上一级组件之中 (App),然后把更新数据的函数当作参数传给 MyInput 组件,这样在子组件里就可以更新上一级组件的里面的信息,然后再把这个数据作为参数传给 MyList 组件,MyList 组件渲染这个列表就有了最简单的 todo 应用的效果
在子组件中更新父组件里面元素的状态:状态在那个组件,更新状态的函数就应该在哪个组件
代码:
// App 组件 class App extends React.Component { constructor(props) { super(props); this.state = { // 用 state 储存输入的内容 todos: [] } this.addtodos = this.addtodos.bind(this); } // 修改 addtodos(todo) { // 获取整个列表 let { todos } = this.state; // 在开头添加数据 todos.unshift(todo); // 渲染回去 this.setState({ todos }); // 不可以这么做:this.state.todos.unshift(todo); } render() { return (<div> <h1>ToDoList</h1> // 把函数当作参数传到子组件上 <MyInput addtodos={this.addtodos} /> <MyList todos={this.state.todos} /> </div>); } } MyInput 组件: class MyInput extends React.Component { constructor(props) { super(props); this.state = { counter: 0, } this.handleClick = this.handleClick.bind(this); } handleClick() { // 设置 button 上的文字 this.setState({ counter: ++this.state.counter }) this.button.innerHTML = "Add #" + this.state.counter; // 调用接收过来的函数 this.props.addtodos(this.input.value); // 清空输入框 this.input.value = null; } render() { return (<div> <input type="text" ref={input => this.input = input} /> <button onClick={this.handleClick} ref={button => this.button = button}>Add #0</button> </div>) } }注意:子组件接收参数是在 props 属性里面接收的
MyList 组件:
class MyList extends React.Component { render() { console.log(this); // 不得不说,React 渲染列表真的很方便 return (<ul>{this.props.todos.map((todo, index) => { return <li key={index}>{todo}</li> })}</ul>) } } // 渲染 App 组件到页面上 ReactDOM.render(<App />, document.querySelector('.innerInput')); 组件化编写功能的流程 拆分组件实现静态组件(只有静态界面,没有动态数据和交互)实现动态组件 1). 实现初始化数据动态显示 2). 实现交互功能阻止默认行为:event.preventDefault()
原生的 onchange 事件是在失去焦点的时候触发,而 React 中的 onChange 事件是在输入的时候就触发事件
取出表单中数据有两种方法:使用 ref 在组件对象上绑定好元素;或者使用 state 属性让输入框内容的值 (value) 等于在 state 中定义的变量,然后监听输入框改变的事件,每在输入框中输入都会更新 state 中的数据 (推荐第二种)
实例:两个输入框分别用 ref 和 state 绑定数据,点击 login 按钮时弹出输入的用户名和密码
class MyCompent extends React.Component { constructor(props) { super(props); this.state = { pwd: '' } this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); } handleSubmit(event) { // 阻止默认行为 event.preventDefault(); console.log(this.nameInput); alert("用户名" + this.nameInput.value + "密码" + this.state.pwd); } handleChange(event) { // 让输入框和 state 中的数据同步 let pwd = event.target.value; this.setState({ pwd }); } render() { return (<form action="" onSubmit={this.handleSubmit}> <label for="name">name:</label> // 使用 ref 将整个元素绑定到组件对象上 <input type="text" id="name" ref={input => this.nameInput = input} /> <label for="password" >password:</label> // 在 state 中绑定数据,并且绑定监听输入框发生改变事件 handleChange <input type="password" id="password" value={this.state.pwd} onChange={this.handleChange} /> <input type="submit" value="login" /> </form>) } } ReactDOM.render(<MyCompent />, document.querySelector(".form")); 受控组件:表单项输入数据能自动收集成状态 (每输入一个数,后台自动更新输入的数据:state 方法)非受控组件:需要时才手动读取表单输入框中的数据 (点击提交按钮的时候才更新数据:ref 方法)官网不推荐使用 refs 推荐使用 state