React小白记录学习历程。
1.安装React(npm5.2+)
npx create-react-app my-app
cd my-app
npm start
在npm命令行执行以上命令即可建立一个react项目,如下图:
此项目为单页应用程序,public文件夹中存放HTML页面和一些静态资源,src中存放js文件其中index.js为默认执行js。
2.渲染
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<h1>欢迎使用react</h1>
,
document.getElementById('root')
);
registerServiceWorker();
在my-app路径下执行npm start
其中使用了JSX和ES6的语法,虽然react不是必须使用,但是推荐使用。
ReactDOM.render(
<h1>欢迎使用react</h1>
,
document.getElementById('root')//选中HTML中的根节点
);
使用ReactDOM.render()将内容渲染到HTML中id为root 的根节点中
3.组件和props属性
组件分为函数组件和类组件
函数组件
function Welcome(props) {//定义一个组件
return <h1>Hello, {props.name}</h1>;
}
props是在使用组件是传入得参数
const element = <Welcome name="react" />;//代表着创建一个组件
ReactDOM.render(
element,
document.getElementById('root')
);
react中props是禁止修改的,在传入时就已确定。如果是嵌套组件切name值由父组件传入则可写为name={},注意无需写引号。
类组件(es6语法)
class App extends Component {//类组件的定义
render() {
return (
<div className="App">
<h1>{this.props.name}</h1>//props.name由this.props.name代替
</div>
);
}
}
类组件在render(return())中return外可以写一些定义,return中写该组件需要输出的内容;
注意:return中不可以存在两个顶级标签。组件名称总是以大写字母开始的。
4.组件的生命周期及state(状态)
class App extends Component {
constructor(props){
super(props)
this.state = {name:''};//state的初始化
}
componentDidMount(){
console.log("挂载,在组件装载(mounting)后被立即调用。");
this.setState({name:'嘟嘟嘟'});
}
componentWillUnMount(){
console.log("卸载,在组件销毁加载时执行此函数中的代码");
}
render() {
return (
<div className="App">
<h1>{this.state.name}</h1>
</div>
);
}
}
以上是组件的生命周期及state,当组件实例被创建并将其插入 DOM 时,将按以下顺序调用这些方法:
1.构造方法
2.render()
3.挂载方法
在组件中state是可以改变的,所以要是做一些与用户交互的时候可以使用state来接受参数。
this.state.name = "嘟嘟嘟"//赋值方式错误
this.setState({name:'嘟嘟嘟'});//必须使用this.setState();
在setState()方法中可以写函数
this.setState(function () {
return {name:"嘟嘟嘟"}
})
提示:如果需要载入时获取后台数据,可以将ajax等放入挂载中.只有state变化才可以重新渲染页面。
5.处理事件&列表&表单
class App extends Component {
constructor(props){
super(props)
this.state = {names:[{name:'React'},{name:'Vue'},{name:'UI'},{name:'JS'}],title:'UI'};//state的初始化
//给事件绑定this(第一种方法)
this.onChanges = this.onChanges.bind(this);
}
componentDidMount(){
}
onChanges(event,id){
//获取当前事件
var target = event.target;
console.log(target);
this.setState(()=>({
title:target.value
}));
}
render() {
return (
<div className="App">
<select onChange={this.onChanges} value={this.state.title}>
{this.state.names.map(
(name,index) => <option key={index} value={name.name}>{name.name}</option>
)}
</select>
<h1>{this.state.title}</h1>
</div>
);
}
}
一个下拉列表,选中哪个下边显示哪个。执行结果:
初始化state
constructor(props){
super(props)
this.state = {names:[{name:'React'},{name:'Vue'},{name:'UI'},{name:'JS'}],title:'UI'};//state的初始化
//给事件绑定this(第一种方法)
this.onChanges = this.onChanges.bind(this);
}
向state中存入了一个数组及一个title属性用来接收下拉列表当前的值
将下拉列表渲染到界面
render() {
return (
<div className="App">
<select onChange={this.onChanges} value={this.state.title}>
{this.state.names.map(
(name,index) => <option key={index} value={name.name}>{name.name}</option>
)}
</select>
<h1>{this.state.title}</h1>
</div>
);
}
react循环输出用items(数组).map((item,index)=>展示的内容)
加入onchange事件
onChanges(event){
//获取当前事件
var target = event.target;
console.log(target);
this.setState(()=>({
title:target.value
}));
}
event.target获取当前元素
注意:在设置事件的时候,需要用bind绑定this。
//给事件绑定this(第一种方法)
this.onChanges = this.onChanges.bind(this);
另一种在标签中,传入额外的参数
<button onClick={() => this.onChanges(id)} />
另一种传参
<button onClick={this.onClick.bind(this,id)}>btn</button>
onClick(id){
console.log(id);
}
提醒:和Vue不同的是react数据是单向的,一些表单效果可通过state实现。
6.React Router4.x(react官方路由)
npm install --save react-router-dom//安装
2.0和4.0两种版本,由差别。
由于我们创建的是一个基于浏览器的应用,我们可以从React Router API中使用这两种类型的路由:
1.<BrowserRouter>
2.<HashRouter>
<BrowserRouter>在两者中更常用是因为它使用了HTML5的history API来记录你的路由历史。
而<HashRouter>
使用URL(window.location.hash
)的hash部分来记录。如果你想兼容老式浏览器,你应该使用<HashRouter>
。
直接上demo吧
index.js中
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<BrowserRouter>//标签得写在最外边
<App name="嘟嘟嘟"/>
</BrowserRouter>
, document.getElementById('root'));
registerServiceWorker();
其他组件js中
import React, { Component } from 'react';
import './App.css';
import { Link,Route } from 'react-router-dom';
function one() {
return <h1>第一个路由</h1>
}
function two() {
return <h1>第2个路由</h1>
}
class App extends Component {
render() {
return (
<div className="App">
<Link to="/one">第一个</Link>//link标签跳转路由
<Link to="/two">第2个</Link>
<div>
<Route path="/one" component={one}/>//路由的定义
<Route path="/two" component={two}/>
</div>
</div>
);
}
}
export default App;
路由的两种传参方式:
import React, { Component } from 'react';
import './App.css';
import { Link,Route } from 'react-router-dom';
function one(props) {
return <h1>第一个路由{props.match.params.data}</h1>//第一种对应接收方法
}
function two(props) {
return <h1>第2个路由{props.location.state.param}</h1>//第二种对应接收
}
class App extends Component {
render() {
const data = "params传参";
return (
<div className="App">
<Link to={"/one/"+data}>第一个</Link>//第一种link对应
<Link to={{pathname:'/two',state:{param:'state传参'}}}>第2个</Link>//第二种只用link声明路径和参数
<div>
<Route path="/one/:data" component={one}/>//第一种params用url拼串,需在路径中声明
<Route path="/two" component={two}/>//第二种路由定义无需变化
</div>
</div>
);
}
}
export default App;
谢谢观看,不足之处还望各位大佬提出。