最近把使用uniapp写的小程序,通过taro使用react框架重新写了一下,
于是简单总结了一下,写了这篇文章方便熟悉Vue的小伙伴们学习React。
安装
- 在html文件中直接引入测试
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
因为是jsx,所以需在写react代码的script标签上,加上 type=“text/babel” 属性
- 使用React脚手架
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start
本文例子使用第一中形式讲解
组件
React定义组件的方式有这两种:
// ES6 class 定义
class Index extends React.Component{
constructor(props){
super(props)
console.log(this.props);
}
render(){
return(
<div>Home</div>
)
}
}
// 函数/无状态/UI组件
function Index(props){
console.log(props);
return(
<div>Home</div>
)
}
//上述两个组件在 React 里是等效的。
...
class App extends React.Component {
render() {
return <Index name="index" message='哈哈哈' good-foo="12312" />;
}
}
ReactDOM.render(
React.createElement(App),
document.getElementById('app')
);
React的props 代表传递给组件的参数
上例props的值:
{ name:‘index’, message:‘哈哈哈’, good-foo:‘12312’}
- 短横线命名的属性也将以短横线属性的形式存在
super()
- 用ES6 class 定义的组件,在constructor中必须使用super()执行父构造函数,当然最好传递props进去
- 使用super()后才可在constructor中使用this
//不在super中传递props
class Index extends React.Component{
constructor(props){
super()
console.log(props); // {...}
console.log(this.props); // undefined
}
render(){
return(
<div>Home</div>
)
}
}
React的默认props (defaultProps)
1. React 组件类中作为为静态属性
//
class Index extends React.Component{
constructor(props){
super(props)
}
//增加
static defaultProps = {
name: 'index页'
}
render(){
return(
<div>Home</div>
)
}
}
2. 作为类或者构造函数的属性
class Index extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<div>Home</div>
)
}
}
// 或者
function Index(props){
return(
<div>
{props.name}
</div>
)
}
Index.defaultProps = {
name: '我是props的默认值!'
}
3. 函数式组件默认值的解构
function Index(props){
const {
name: '我是props的默认值!'
} = props
return(
<div>
{props.name}
</div>
)
}
React的’data’ state
1.定义state初始值
- 在render函数里通过解构state的值就可直接使用
class Index extends React.Component{
constructor(props){
super(props)
this.state = { //增加
name:'张三',
age:18
}
}
render(){
const { name, age } = this.state // 增加
return(
<div>
<div>{this.props.name}</div>
<ul>
<li>{name}</li>
<li>{age}</li>
</ul>
</div>
)
}
}
Index.defaultProps ={
message: '我是props的默认值!'
}
class App extends React.Component {
render() {
return <Index name='index' message='哈哈哈' good-foo="12312" />;
}
}
ReactDOM.render(
React.createElement(App),
document.getElementById('app')
);
2. 修改state中的值
setState()
- 更新状态基本用法:
// Vue修改data的 age值
// this.age = 20
// React修改state的 age值
this.setState({
age:20
})
- 更新状态之前获取旧值的用法
- prevState 代表将要改变 state 的age值前的 state
- props 代表传入的props
this.setState((prevState,props)=>{
console.log(prevState,props);
return{
age:20
}
})
- 更新状态后调用的用法
- 有点类似在使用vue的$nextTick()的地方,部分业务代码可以用这个用法
this.setState({
age:20
},()=>{
// 当更新完age的值后执行
})
React的’computed’
- Vue
computed:{
renderFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
- React
class Example extends Component {
constructor(props){
super(props)
this.state = {
firstName: '',
lastName: '',
}
}
renderFullName() {
const { firstName, lastName } = this.state;
return `${firstName} ${lastName}`;
}
render() {
const renderFullName = this.renderFullName()
return <div>{renderFullName}</div>;
}
}
- 当然这里也可以使用react的hook实现
React的’watch’
监听props的 obj属性 初始化执行一次
- Vue
props:{
obj:{
type:Object,
defaule:()=>{
name:'张三',
age:20
}
}
}
watch:{
obj:{
immediate: true,
handler:function(val,oldval){
console.log(val.name)
}
}
}
- React
class Content extends React.Component {
constructor(props){
super(props)
}
static defaultPros = {
obj:{
name:'张三',
age:20
}
}
componentWillReceiveProps(newProps){
if(newProps.obj === this.props.obj){
console.log(this.props.obj.name)
}
}
componentDidMount() {
console.log(this.props.obj.name)
}
}
- 通过使用componentWillReceiveProps钩子函数 获取newProps
- 这里监听obj对象,需要对比新旧props判断obj是否变化 在进行其他处理
- 通过使用componentDidMount钩子函数 类似 Vue的mounted ,进行初始执行一次
- 当然这里也可以使用react的hook实现也更简单
React定义函数
class Index extends React.Component{
constructor(props){
super(props)
this.state = { //增加
name:'张三',
age:18
}
this.handleClick1 = this.handleClick1.bind(this)
this.handleClick2 = this.handleClick2.bind(this)
}
//增加
handleClick1(){
// this.props
// this.state
console.log('handleClick1---')
}
handleClick2(event,name){
console.log('handleClick2---',event,name)
}
render(){
const { name, age } = this.state // 增加
return(
<div>
<div>{this.props.name}</div>
<ul>
<li onClick={this.handleClick1}>{name}</li>
<li onClick={(event)=>{this.handleClick2(event,name)}}>{age}</li>
</ul>
</div>
)
}
}
关于函数
handleClick1: 可以获取 this.props 和 this.state 写一些业务
handleClick2: 写成回调函数的形式,可以传递事件对象,以及一些其他数据
handleClick2不能不加一层函数,这里类似于React编译的时候会把函数体直接放在这里,会被直接调用
通过bind 绑定函数的this 指向, 通过 this调用函数,会存在this指向丢失的情况