React 学习笔记

查看更详细教程,请阅读 React官方文档

一、搭建环境

1、方式1:在网站中直接引入使用

<script src="//www.w3cschool.cn/statics/assets/react/react.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/react-dom.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/babel.min.js"></script>

实现 hello world ! 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>react</title>
    <script src="//www.w3cschool.cn/statics/assets/react/react.min.js"></script>
    <script src="//www.w3cschool.cn/statics/assets/react/react-dom.min.js"></script>
    <script src="//www.w3cschool.cn/statics/assets/react/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('app')
      );
    </script>
  </body>
</html>

注意:script标签内type属性需要填写为 type = "text/babel";

 

2、方式2:使用脚手架搭建本地环境

npm install create-react-app -g    // 安装react-react-app
create-react-app react_test  // 创建项目,项目名:react_test
cd react_test  // 进入项目根目录下
npm start  // 启动react项目,启动成功会自动在浏览器上启动

默认项目结构

react_test/
  README.md
  node_modules/        // node环境项目依赖
  package.json         // 项目配置依赖文件
  public/              // 公共静态资源文件夹
    index.html         // 项目入口模板文件
    favicon.ico
  src/
    App.css
    App.js              // 默认app主入口
    App.test.js
    index.css
    index.js            // 项目渲染主文件
    logo.svg

 

二、React 基础

1、元素

元素是构成 React 应用的最小砖块,如下是一个元素

const element = <h1>hello world!</h1>

元素渲染

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

2、组件

定义组件(函数组件)

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

还可以使用es6的class语法进行定义组件(等效于普通函数组件)

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

渲染组件

function App(){
    return (
        <div>
            <Welcome name="小书包" />
            <Welcome name="小书包2" />
            <Welcome name="小书包3" />
        </div>
    )
}
ReactDOM.render(App, document.getElementById('root'));

  • 组件可以多次复用
  • 组件上可以通过属性名传递参数,组件内通过props参数接收,props是一个对象。

 

3、state

state一般用于组件内的数据展示,可以通过改变state以改变组件的状态。

下面是一个显示当前时间的组件:

class Clock extends React.Component {
	constructor(props) {
		super(props)
		this.state = {
	          date: new Date(),
		}
	}
	render() {
	    return (
	      <div>
	        <h2>当前时间:{this.state.date.toLocaleTimeString()}</h2>
	      </div>
	    );
	}
}

我们可以在构造方法中定义我们要使用的state,然后可以在组件中使用。注意:在每一个组件中调用一次super是必须的,才能在组件中获得react的实例方法并使用。

此例子显示了当前当前渲染的时间,但是不会更新当前时间,下面是一个会自动更新时间的例子:

class Clock extends React.Component {
	constructor(props) {
		super(props)
		this.state = {
			date: new Date(),
		}
	}
	componentDidMount() {    // 组件生命周期:组件加载完成后调用
		setInterval(()=>{
			this.setState({date:new Date()})
		},1000)
	}
	render() {
	    return (
	      <div>
	        <h2>当前时间:{this.state.date.toLocaleTimeString()}</h2>
	      </div>
	    );
	}
}

我们可以通过this.setState去更改state,实现实时更新state状态。react会根据state中的数据变化,为对应的部分进行渲染更新。

注意:state仅能通过this.setState方法进行更新state,不能直接通过this.state进行更新。

state的数据是向下流的:

父组件的state可以给子组件使用,但是子组件的state不能反过来给父组件使用。

 

4、事件

在标签或组件上绑定事件:

<button onClick={this.handleClick}>点击</button>

其中handleClick是组件内的一个方法。值得注意的是:以前我们阻止一个事件的默认行为可以通过 return false实现,在react中,我们需要通过在方事件法中调用e.preventDefault()

function handleClick(e) {
    e.preventDefault();
}

下面是一个开关状态切换的示例:

class Toggle extends React.Component {
	constructor(){
		super();
		this.state = {
			open: true
		}
		this.toggle = this.toggle.bind(this)  // 一般我们都会将toggle方法绑定到this实例
	}
	toggle(){
		this.setState({
			open: !this.state.open
		})
	}
	render(){
		return (
			<button onClick={this.toggle}>{this.state.open ? '开' : '关'}</button>
		)
	}
}

注意:我们需要将方法绑定到实例对象上,否则无法实例的方法与数据。

或者我们还可以在标签上绑定事件时使用一个箭头函数。

<button onClick={() => this.toggle()}>{this.state.open ? '开' : '关'}</button>

事件传参:

<button onClick={() => this.toggle("这是传递的参数")}>{this.state.open ? '开' : '关'}</button>

//以下等值
<button onClick={this.toggle.bind(this,"这是传递的参数")}>{this.state.open ? '开' : '关'}</button>

 

5、条件渲染

在函数组件内条件判断输出:

function Condition(){
	if(true){
		return <h1>条件为真时输出我!</h1>
	}
	return <h1>条件为假时输出我!</h1>
}

也可以通过jsx中判断输出:

render(){
    return(
        {   
            2 > 1 && <h1>前面表达式成立才会有我的输出哦</h1>
        }
    )
}

&&与运算只要两者都为真,必定会返回第二者

还可以通过三元运算输出:

render(){
    return(
        {   
            2 > 1 ? <h1>条件成立</h1> : <h1>条件不成立</h1>
        }
    )
}

 

6、列表渲染

我们可以在函数组件中使用 javascript 的循环逻辑进行组装组件,示例如下:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

上面这段代码运行会提示 a key should be provided for list items,虽然不会导致运行错误,但是可能会性能较差。

我们应该为列表中的每一项添加一个唯一的 key,一般可以使用每一项的id值作为key。

const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );

列表渲染我们还可以在 JSX 中实现。

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {
        numbers.map((number) =>
            <ListItem key={number.toString()} value={number} />
        )
      }
    </ul>
  );
}

 

7、表单

在react中,表单元素使用的是受控组件开发,下面看看什么是受控组件

受控组件:

表单元素(如:input、textarea、select)是组件内的state进行控制显示,而不是由元素自身进行控制。对元素进行事件监听获得输入内容再传递给state进行保存,而实现state控制元素的内容显示。示例如下:

class Form extends React.Component {
	constructor(){
		super()
		this.state = {
			name: '', // 给定的name值
		}
		this.nameInput = this.nameInput.bind(this)
	}
	nameInput(e){
		this.setState({
			name: e.target.value
		})
	}
	render(){
		return (
			<input type="text" value={this.state.name} onChange={this.nameInput} />
		)
	}
}

textarea 标签:
在html中给textarea指定默认值如下:

<textarea>这是默认值</textarea>

但是在JSX中,指定默认值是通过value属性,监听用户输入 onChange。与input十分相似。

<textarea value={this.state.value} onChange={this.nameInput} />

select 标签:

在html中指定选中项是这样的:

爱好:
<select>
	<option value="1">踢足球</option>
	<option checked value="2">唱歌</option>
	<option value="3">跳舞</option>
</select>

在 JSX 中,不使用checked,依然使用 value 绑定选中项,onChange 监听选择,示例如下:

爱好:
<select value={this.state.hobby} onChange={this.hobbyChange}>
    <option value="1">踢足球</option>
    <option value="2">唱歌</option>
    <option value="3">跳舞</option>
</select>

select 多选可以这样做:

添加属性multiple={true},value接受一个数组

<select multiple={true} value={['1', '2']} onChange={this.hobbyChange}>
	<option value="1">踢足球</option>
	<option value="2">唱歌</option>
	<option value="3">跳舞</option>
</select>

这个例子将会默认选中第一、二项,

 

处理多个值输入:

可以给每一个input添加一个name属性,并给定值。可以通过一个方法对多个输入进行赋值:

class Form extends React.Component {
	constructor(){
		super()
		this.state = {
			name: '', // 姓名
			remark: '', // 备注
		}
		this.valueInput = this.valueInput.bind(this)
	}
	valueInput(e){
		let value = e.target.value;
		let name = e.target.name;
		this.setState({
			[name]: value
		})
	}
	render(){
		return (
			<form>
				<input name="name" type="text" value={this.state.name} onChange={this.valueInput} />
				<textarea name="remark" value={this.state.remark} onChange={this.valueInput} />
			</form>
		)
	}
}

 

8、状态提升

当多个组件需要使用到同一数据时,我们应该将这一状态提取到公共的父组件去,我们知道state的数据是向下流的。这成为react的状态提升。

 

9、组合

有时候,我们需要在另一个组件中插入我们需要的内容,我们应该如何实现呢,react已经为我们提供了非常强大的组合功能。

在组件元素中插入的内容将会传递到 props.children 中:

function Concat(props){
	return (
		<div>
			<div>我的后面可以插入内容</div>
			<div>{props.children}</div>
		</div>
	)
}
ReactDOM.render(
  <Concat>
      <h1>这是我插入的内容</h1>
  </Concat>,
  document.getElementById('root')
);

学过vue的可能会想起 “插槽slot”,在react中是没有插槽这个概念的。

插槽slot可以提供多个slot,即多个地方插入内容,那么react是如何实现的呢

我们知道props是可以传递任何类型的数据的,也包括标签元素,组件。所以我们可以将所需内容通过props传递,示例如下:

function Concat(props){
	return (
		<div>
			<div>内容一:{props.content1}</div>
			<div>内容二:{props.content2}</div>
		</div>
	)
}
ReactDOM.render(
  <div>
      <Concat content1={<h1>这是内容一</h1>} content2={<h1>这是内容二</h1>}></Concat>        
   </div>,
  document.getElementById('root')
);

tips:因为react的组合功能足够强大,组件也可以是另一个组件的元素,所以react认为,不需要继承,在react 中没有继承概念。

 

三、React使用less

1、安装 less、less-loader

npm install less less-loader --save

2、释放配置

npm run eject

执行结束后,可以看到比原来多了以下目录(webpack配置文件)

3、配置

配置 config/webpack.config.js

在合适的位置添加以下规则

// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

const lessRegex = /\.less$/;        // 新增
const lessModuleRegex = /\.module\.less$/;     // 新增

找到以下配置,添加红框标识内容

找到以下内容,并在同层次位置添加以下内容

{
    test: lessRegex,
    exclude: lessModuleRegex,
    use: getStyleLoaders(
        {
            importLoaders: 1,
            sourceMap: isEnvProduction && shouldUseSourceMap,
        },
        'less-loader'
    ),
    sideEffects: true,
},
{
    test: lessModuleRegex,
    use: getStyleLoaders(
        {
            importLoaders: 1,
            sourceMap: isEnvProduction && shouldUseSourceMap,
            module: true,
            getLocalIdent: getCSSModuleLocalIdent
        },
        'less-loader'
    ),
},

到此配置已经完成,重启项目检查。

 

注:个人笔记,不作为标准答案,仅供参考,不喜勿喷!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值