React初识
一、介绍与安装
1、介绍
以上内容均参考慕课网公开课视频 https://www.imooc.com/learn/1045 基于实例的 React16 傻瓜课程
A JavaScript library for building user interfaces
官方网站 https://reactjs.org/
文章主要内容说明
主要技术内容
- 官网提供的脚手架 my-project
- 使用命令可直接获取该项目
- create-react-app my-project
实现内容介绍
- NameCard.js 个人名片 Props属性
- LikesButton.js 点赞 State状态
- DigitalClock.js 时钟 生命周期
- CommentBox.js 留言板 输入框
- CommentList.js 留言列表
2、环境安装
安装node
访问nodejs官网(https://link.jianshu.com/?t=https://nodejs.org/en/),下载安装包,直接安装
终端命令查看
npm -v
node -v
看是否安装成功,如果有版本号输入则安装成功
新建一个js文件,test.js , 输入下面的代码, 并保存
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {
"Content-Type" : "text/plain"
});
response.write("Welcome to Nodejs");
response.end();
}).listen(8000, "127.0.0.1");
console.log("Creat server on http://127.0.0.1:8000/");
打开终端进入 test.js 所在目录, 输入 test 便可以打开浏览器访问
参看链接
Mac 安装nodejs https://www.jianshu.com/p/90c01b7bd3cb
快速构建
create-react-app 是来自于 Facebook,通过该命令我们无需配置就能快速构建 React 开发环境。
create-react-app 自动创建的项目是基于 Webpack + ES6 。
安装
npm install create-react-app -g
创建项目
create-react-app my-project
启动项目 需要在项目目录下
npm start
3、快速开始
在上述项目中src目录创建文件Welcome.js
import React from 'react'
class Welcome extends React.Component {
render() {
const isLogin = true
return (
<div>
<h1> Hello React . </h1>
{1+2}
{isLogin ? <p>您已经登陆</p> : <p>请登陆</p>}
</div>
)
}
}
export default Welcome
在src目录下的index.js中修改
添加
import Welcome from './Welcome';
// 两个参数
ReactDOM.render(<Welcome />, document.getElementById('root'));
启动项目变可以看到

二、功能介绍
1、JSX语法
- 类似于HTML
- JavaSript的语法扩展
- 可以使用花括号{}内嵌任何JavaScrip表达式(Expressions)
- JSX 熟悉 主要保留关键字
render() {
const isLogin = true
return (
<div>
<h1> Hello React . </h1>
{1+2}
{isLogin ? <p>您已经登陆</p> : <p>请登陆</p>}
</div>
)
}
babel编译


BABEL编译效果
<h1 className='inco'> hh
<spen> BABEL </spen>
</h1>
React.createElement("h1", {
className: "inco"
}, " hh", React.createElement("spen", null, " BABEL "));
===========================================
<div>
<h1> Hello React . </h1>
</div>
React.createElement("div", null, React.createElement("h1", null, " Hello React . "));
ReactDOM.render(<Welcome />, document.getElementById('root'));
即实现该效果
- JSX是一种语法糖——React.createElement()
- ReactElement对象 即经常复杂的算法转化成一个Object
2、Props/State/Forms属性和状态
Props属性——名片
属性Props示例——一张名片
Props:示例-名片
Viking
- 电话:1327897897
- 外星生物
好像印象:体育健将、单机游戏爱好者

安装bootstrap样式
npm install bootstrap --save
代码示例
1、新建NameCard.js,在src目录下
import React from 'react'
class NameCard extends React.Component {
render() {
const { name, number, isHuman, tags } = this.props
return (
<div className="alert alert-success">
<h4 className="alert-heading">{name}</h4>
<ul>
<li>电话:{number}</li>
<li>{ isHuman ? '人类' : '外星生物'}</li>
<hr/>
<p>
{tags.map(
(tag, index) => (
<span className="badge badge-pill badge-primary" key={index}>{tag}</span>
)
)}
</p>
</ul>
</div>
)
}
}
export default NameCard
2、引入到src下的App.js
import NameCard from './components/NameCard';
const tags = ["读书🌆", "吉他🎸", "音乐🎵"]
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
</header>
{/* 自定义名片 */}
<NameCard name="Elijah" number={7890567} isHuman tags={tags} />
</div>
);
}
3、index.js下引入App.js
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'
// 两个参数
ReactDOM.render(<App />, document.getElementById('root'));
展示效果

优化函数:
替换NameCard.js的类为函数,该函数上声名式函数,不允许替换变量
const NameCard = (props) => {
const { name, number, isHuman, tags } = props
// 给name赋值会报错,只能传即进来值
return (
<div className="alert alert-success">
<h4 className="alert-heading">{name}</h4>
<ul>
<li>电话:{number}</li>
<li>{ isHuman ? '人类' : '外星生物'}</li>
<hr/>
<p>
好友印象:
{tags.map(
(tag, index) => (
<span className="badge badge-pill badge-primary" key={index}>{tag}</span>
)
)}
</p>
</ul>
</div>
)
}
State状态——点赞
- 组件内部的数据可以动态改变
- this.setState()是更新state的唯一途径
代码示例
通过点击,增开数字上涨
1、新建LikesButton.js 文件
import React from 'react'
class LikesButton extends React.Component {
constructor(props) {
super(props)
this.state = {
likes: 0
}
// 定义方法
//this.increaseLikes = this.increaseLikes.bind(this)
// 调用方法 onClick={this.increaseLikes}
}
render() {
return (
<div className="like-button-component">
<button type="button"
className="btn btn-outline=primary btn-lg"
onClick="fun()"
//onClick={this.increaseLikes}
//声名式函数
onClick={ () => {this.increaseLikes()}}
>
👍{this.state.likes}
</button>
</div>
)
}
increaseLikes() {
// alert(777)
// console.log(this)
this.setState({
likes: ++this.state.likes
})
}
}
// 类导出
export default LikesButton
2、引入文件到App.js
import LikesButton from './components/LikesButton';
function App() {
return (
<div className="App">
<LikesButton />
</div>
);
}
3、展示效果

生命周期——时钟
- 组件初始化
- 组件更新
- 组件卸载
用时钟来展示
代码示例
1、新建DigitalClock.js,在src下
import React from 'react'
class DigitalClock extends React.Component {
constructor(props) {
super(props)
this.state = {
date: new Date()
}
}
render() {
return (
<div className="digital-clock-component jumbotron">
<h1>
{this.state.date.toLocaleTimeString()}
</h1>
</div>
)
}
// 定时器
componentDidMount() {
this.timer = setInterval(
() => {
this.setState({
date: new Date()
})
}, 1000
)
}
// 清除时间
componentWillUnmount() {
clearInterval(this.timer)
}
//打印
componentDidUpdate(currentProos, currentState) {
console.log(currentState)
}
}
export default DigitalClock
代码效果展示

控制台打印

拓展应用
- componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
- componentWillUnmount在组件从 DOM 中移除之前立刻被调用。
- componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
- componentDidMount: 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
参考菜鸟教程 https://www.runoob.com/react/react-component-life-cycle.html
Forms表单——留言框
- 表单元素和其他DOM元素的区别
- Controlled Components —— 受控组件
代码示例
CommentBox.js
// 留言框 form 表单
import React from 'react'
class CommentBox 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 className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言内容</label>
<input type="text" className="form-control"
placeholder="请输入内容"
onChange={this.handleChange}
value={this.state.value} />
</div>
<button type="submit" className="btn btn-primary">
留言
</button>
</form>
)
}
}
export default CommentBox
更改点击事件方式
handleSubmit(event) {
alert(this.textInput.value)
// alert(this.state.value) onChange
// 重新提交之后页面跳转
event.preventDefault()
}
render() {
return (
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言内容</label>
<input type="text" className="form-control"
placeholder="请输入内容"
// onChange={this.handleChange} value={this.state.value}
ref={(textValue) => this.textInput = textValue}
/>
</div>
<button type="submit" className="btn btn-primary">
留言
</button>
</form>
)
}

3、综合实例-留言板

[]:
状态提升与单向数据流
代码展示
评论列表 新建CommentList.js
import React from 'react'
const CommentList =({comments}) => {
return (
<div className="comment-list-component">
<label>评论列表</label>
<ur className="list-group mb-3">
{
comments.map(
(comment, index) => <li key={index} className="list-group-item">{comment}</li>
)
}
</ur>
</div>
)
}
export default CommentList
留言组件
// 留言框 form 表单
import React from 'react'
class CommentBox 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.textInput.value)
// alert(this.state.value) onChange
// 外部传入数据
this.props.onAddcomment(this.textInput.value)
// 重新提交之后页面跳转
event.preventDefault()
//留言成功之后,清除留言框数据
}
render() {
return (
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言内容</label>
<input type="text" className="form-control"
placeholder="请输入内容"
// onChange={this.handleChange} value={this.state.value}
ref={(textValue) => this.textInput = textValue}
/>
</div>
<button type="submit" className="btn btn-primary">
留言
</button>
<p>已有{this.props.commentsLength}条评论</p>
</form>
)
}
}
export default CommentBox
主页面 App.js
import React from 'react'
import LikesButton from './components/LikesButton';
import DigitalClock from './components/DigitalClock';
import CommentBox from './components/CommentBox';
import CommentList from './components/CommentList';
class Welcome extends React.Component {
constructor(props) {
super(props)
this.state = {
comments: ["my frist reply"]
}
this.addComment = this.addComment.bind(this)
}
addComment(comment) {
this.setState(
{
// 将新的commen添加到comments数组中
comments: [...this.state.comments, comment]
}
)
}
render() {
const isLogin = true
const test = <h1> Hello React </h1>
console.log(test)
const {comments} = this.state
return (
<div>
{/* 时间显示 */}
<DigitalClock />
{/* 评论列表 */}
<CommentList comments={comments}/>
{/* 留言板 */}
<CommentBox
commentsLength={comments.length}
onAddcomment={this.addComment}
/>
</div>
)
}
}
export default Welcome
效果展示

React 开发思想以及和其他思想的异同
- 状态提升(lifting state up)
- 自上而下的数据流(top-down data flow )
- 和双向绑定的区别
4、Context
Context是什么
- Props属性是由上到下单向传递的
- Context提供了在组件中共享此类值的方法
Context使用
- 设计目的是共享那些对于组件来说全局的数据
- 不要仅仅为了避免在几个层级下的组件传递props而实用context
使用props传递属性可能会设计到多文件直接的数据流动,甚至有些文件不需要这个属性如语言,用户信息等,则采用context共享数据。
context实例 ——样式选择器
深色主题与浅色主题的互换
代码示例
选择颜色
新建theme-context.js 在src下
import React from 'react'
const ThemeContext = React.createContext()
export default ThemeContext
颜色展示组件
ThemedBar.js
import React from 'react'
import ThemeContext from '../theme-context'
const ThemeBar = () => {
return (
<ThemeContext.Consumer>
{
theme => {
return(
<div className="alert mt=5" style={ {backgroundColor: theme.bgColor, color: theme.color}}>
样式区域
<button className={theme.classNames}>样式按钮🔘</button>
</div>
)
}
}
</ThemeContext.Consumer>
)
}
export default ThemeBar
面板
APP.js
import React from 'react'
import DigitalClock from './components/DigitalClock';
import ThemeContext from './theme-context';
import ThemeBar from './components/ThemedBar';
const themes = {
light: {
classNames : 'btn btn-primary',
bgColor: '#eeeeee',
color: '#000'
},
dark: {
classNames : 'btn btn-light',
bgColor: '#222222',
color: '#fff'
}
}
class ContextColor extends React.Component {
constructor(props) {
super(props)
this.state = {
theme: 'light'
}
this.changeTheme = this.changeTheme.bind(this)
}
changeTheme(theme) {
this.setState(
{
theme
}
)
}
render() {
return (
<div>
{/* 主题切换 */}
<ThemeContext.Provider value={themes[this.state.theme]}>
{/* 时间显示 */}
<DigitalClock />
<div className="App">
<a href="#theme-switcher" className="btn btn-light" onClick={() => {this.changeTheme('light')}} > 浅色主题 </a>
<a href="#theme-switcher" className="btn btn-seconday" onClick={() => {this.changeTheme('dark')}} > 深色主题 </a>
</div>
<ThemeBar />
</ThemeContext.Provider>
</div>
)
}
}
export default ContextColor
页面展示


总结
简单的react入门知识,对于后端技术或者初学者是个不错的选择。比较现在只会html和js已经不行了。
2020/03/25于许昌
网友评论