函数式组件 props.name,类式组件this.props.name
**react 支持三种方式获取 ref,传统的字符串 ref,React.createRef(),回调函数,第一种需要从 refs 上去读取,第二种需要访问 myRef.current,回调函数写法:
<input type=“text” ref={(node) => {this.myRef = node}} />
你可以直接通过你声明的 myRef 直接访问,但是现在使用最多的其实还是 React.createRef,相应的 hooks 为 useRef()。**
表达式==能得到一个值
注意: 组件名称必须以大写字母开头。
函数式组件 function props.name取值 class组件 this.props.name取值
构造函数指的是constructor
使用箭头函数可以不bind
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
button这个变量 储存了两个组件,LogoutButton 和LoginButton
class NameForm 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) {
alert('提交的名字: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
名字:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="提交" />
</form>
);
}
}
input的Value本来是有自己的值的。但是现在绑定了state里的value,并且每次onchange的时候又通过setstate改变了state里的value值,有点像Vue的v-model了?所以变成了一个受控组件
跟input差不多
普通HTML
react受控组件
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('你喜欢的风味是: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
选择你喜欢的风味:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">葡萄柚</option>
<option value="lime">酸橙</option>
<option value="coconut">椰子</option>
<option value="mango">芒果</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
状态提升
,将多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,便可实现共享 state。这就是所谓的“状态提升”。
react路由
App,js文件
import React, { Component } from 'react';
import { Link,Route } from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap'
export default class App extends Component {
render() {
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header"><h2>React Router Demo</h2></div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 原生html 要靠<a>跳转不同的页面 */}
{/* <a className="list-group-item" href="./about.html">About</a>
<a className="list-group-item active" href="./home.html">Home</a> */}
{/* 在React中靠路由链接实现切换组件 */}
<Link className="list-group-item" to="/home">Home</Link>
<Link className="list-group-item" to="/about">About</Link>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
<Route path="/home" component={Home}/>
<Route path="/about" component={About}/>
</div>
</div>
</div>
</div>
</div>
)
}
}
react的路由是
<Link Link className="list-group-item" to="/home">Home</Link>
这里作为a一样的链接
{/* 注册路由 */}
<Route path="/home" component={Home}/>
这里作为注册路由
而Vue的路由是 由router统一管理定义注册 然后 router-link 作为a一样的链接,router-view作为组件占位。(到时候匹配到哪个组件就展示那个组件)
react的嵌套路由
News 组件代码
import React, { Component } from 'react'
export default class News extends Component {
render() {
return (
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
)
}
}
Message 组件代码
import React, { Component } from 'react'
export default class Message extends Component {
render() {
return (
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</div>
)
}
}
Home组件代码
import React, { Component } from 'react'
import MyNavLink from '../../components/MyNavLink'
import { Route,Switch } from 'react-router-dom'
import News from './News'
import Message from './Message'
export default class Home extends Component {
render() {
console.log('路由组件', this.props)
return (
<div>
<h3>我是Home的内容</h3>
<div>
<ul class="nav nav-tabs">
<li>
{/* 注册子路由时要写上父路由的path值 */}
<MyNavLink to="/home/news">News</MyNavLink>
</li>
<li>
<MyNavLink to="/home/message">Message</MyNavLink>
</li>
</ul>
{/* 注册路由 */}
<Switch>
{/* 注册子路由时要写上父路由的path值 */}
<Route path="/home/news" component={News}/>
<Route path="/home/message" component={Message}/>
</Switch>
</div>
</div>
)
}
}
home组件里有嵌套,那么路由的匹配就在home组件里进行,区别于Vue 还有children
向路由组件传递参数
1.params参数
路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收参数:this.props.match.params
2.search参数
路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.search
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
3.state参数
路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.state
备注:刷新也可以保留住参数
编程式路由导航
借助this.prosp.history对象上的API对操作路由跳转、前进、后退
this.prosp.history.push()
this.prosp.history.replace()
this.prosp.history.goBack()
this.prosp.history.goForward()
this.prosp.history.go()
Vue是this.$router.push()
.BrowserRouter与HashRouter的区别
1.底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。
2.path表现形式不一样
BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
HashRouter的路径包含#,例如:localhost:3000/#/demo/test
3.刷新后对路由state参数的影响
1).BrowserRouter没有任何影响,因为state保存在history对象中。
2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。
redux
redux精简版
createstore创建store,,reducer处理数据,页面事件中dispatch