react杂记

React

webpack+react (hello world)

项目结构:
src:
app.js
main.js
package.json
webpack_dev_config.js

需要安装包:
yarn add react react-dom --save


app.js

import React, {component} from 'react';
class App extends Component {
render(){
return (


hello world

)
}
}
export default App

注意:

return 最外一层的div不能破坏,内容全部写在div里面

浏览器不识别jsx,所以用babel来转换
见webpack_dev_config.js中的配置
网页地址:
https://babeljs.cn/docs/setup/#installation


main.js(导入根组件,并渲染根组件)

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
ReactDOM.render(
, document.getElementById('root'));

注意:

如果App.js的导出是
export App
则引入时应该是
import {App} from 'xxxxx'


webpack_dev_config.js

配置babel:

https://babeljs.cn/
https://babeljs.cn/docs/setup/#installation //详情看这个

1. 安装包
yarn add babel-loader babel-core --dev
//转es6
yarn add babel-preset-env --dev
//转换jsx,并添加 "react" 到你的 .babelrc 的 presets 数组中。
yarn add babel-preset-react --dev

开发阶段:

网址:

https://github.com/jantimon/html-webpack-plugin

结合webpack-dev-server 配合 html-webpack-plugin

1. 安装包
yarn add webpack html-webpack-plugin webpack-dev-server --dev

代码:

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/main.js',
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './template.html',
filename: 'index.html'
})
]
}


package.json

配置scripts

"scripts": {
"dev": "webpack-dev-server --progress --open --config webpack_dev_config.js --prot 6008"
}


.babelrc

{
"presets": [
"env",
"react"
]
}


脚手架

参考地址:
https://doc.react-china.org/docs/installation.html

npm install -g create-react-app
create-react-app my-app


热更新(非脚手架项目)

参考地址:
https://github.com/gaearon/react-hot-loader
1.
yarn add react-hot-loader --dev
yarn add babel-polyfill --dev

2.
// .babelrc
{
"presets": [
["env",
{
"modules": false
}],
"react"
],
"plugins": ["react-hot-loader/babel"]
}

3.
https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr

4.
// webpack.config.js
module.exports = {
entry: ['babel-polyfill', 'react-hot-loader/patch', './main.js'],
}
Note: Make sure to set the output.publicPath property to "/" as well. Otherwise hot reloading won't work as expected for nested routes.

5.
// main.js
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './containers/App'

const render = Component => {
ReactDOM.render(


,
document.getElementById('root'),
)
}

render(App)

// Webpack Hot Module Replacement API
if (module.hot) {
module.hot.accept('./containers/App', () => {
render(App)
})
}

Note: To make this work, you'll need to opt out of Babel transpiling ES2015 modules by changing the Babel ES2015 preset to be ["es2015", { "modules": false }]

6.
"scripts": {
"dev": "webpack-dev-server --progress --open --config webpack_config_dev.js --port 6008 --hotOnly"
}

热更新(脚手架生成的项目)

只需要在根目录下运行npm run eject,目录结构会改变

https://github.com/gaearon/react-hot-loader

Migrating from create-react-app里面跟着做三步


React对css、less、sass处理

1. 直接在标签里通过style写
1. <div style={{color:'red'}}>
hello world123

<span style={{ fontSize : 16 + "px"}}>Hello, yoona;
2. 放在单独的对象中
const style = {
color: 'green'
}


hello world

2. 通过外部样式来写
import 'xxxx.css/xxx.less/xxx.sass'
//需要安装loader
// style-loader css-loader less-loader sass-loader node-sass(这个用cnpm装)
//yarn add style-loader css-loader --dev


hello world123

注意:
在jsx中,属性名称后面的值,两种情况,一种字符串,一种{}


组件-----有状态组件,无状态组件

组件的数据来源于两部分
1. 父组件
2. 自己内部数据

无状态组件:
自己内部没有数据,数据来源于父组件

有状态组件:
即可有父组件数据,也可以有自己内部数据

无状态组件

语法:

import React from 'react'
function Hello (){
return (

123

)
}
export default Hello

传值:

传值方:
通过属性名称=值的方式传递

接收方:
function Hello (props){
return (

123,{props.name}

)
}

注意:
父组件传过来的值只能展示,不能直接修改

有状态组件

语法:

class Welcome extends React.Component {
render() {
return

Hello, {this.props.name}

;
}
}

传值:

传值方:
通过属性名称=值的方式传递

接收方:
通过{this.props.name}

私有的值:
constructor(){
super()
this.state = {
name: 'tom'
}
}
使用: {this.state.name}

默认值(es7):
包:babel-preset-stage-0
.babelrc中添加"stage-0"

static defaultProps = {
initCount: 300
}

调用函数

<button onClick={()=>{this.clickme()}}>点我

clickme(){
console.log(1)
}


这种绑定是拿不到this的

改变内部数据

this.setStatus({
name: "yoona"
})


prop-types检查类型 15.0+之后

import PropTypes from 'prop-types'

static propTypes = {
initCount: PropTypes.number/string
}

生命周期

componentWillMount(){}
render(){}
componentDidMount(){}
componentWillReceiveProps(){}
shouldComponentUpdate(){
return true
}
componentWillUpdate(){}
componentDidUpdate(){}

集成 Ant-Design

参考地址:
https://ant.design/docs/react/introduce-cn

1. 安装
yarn add antd

2. import { DatePicker } from 'antd';

3. import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'

按需导入:
1. // .babelrc or babel-loader option
{
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // style: true 会加载 less 文件
]
}
然后只需从 antd 引入模块即可,无需单独引入样式

参考地址:https://github.com/ant-design/babel-plugin-import

2. 手动按需导入
import DatePicker from 'antd/lib/date-picker';
// 加载 JS
import 'antd/lib/date-picker/style/css';
// 加载 CSS

react-router-dom

参考地址:
https://reacttraining.com/react-router/web/example/basic

yarn add react-router-dom --save

fetch-jsonp

yarn add fetch-jsonp --save

import fetchJsonp from 'fetch-jsonp'

getFilmList(){
const url = https://api.douban.com/v2/movie/${this.state.filmType}
fetchJsonp(url).then(response=>response.json()).then(data=>{
this.setState({
isLoading: false,
filmList: data.subjects
})
}).catch(e=> console.log('error',e))
}

改变数据时:

componentWillReceiveProps(props){
this.setState({
filmType: props.match.params.filmTypes,
isLoading: true
},()=>{
this.getFilmList()
})
}

render里面需要遍历时用{}

render() {
if(this.state.isLoading){
return


}else{
return (
<div style={{display:'flex',flexWrap:'wrap',textAlign:'center'}}>
{
this.state.filmList.map((item,i)=>{
return <div key={i} onClick={()=>{this.goMovieDetail(item.id)}} className="movieItem" style={everyMovieItemStyle}>

{item.title}


电影类型:{item.genres.join(',')}


上映年份:{item.year}


评分:<Rate disabled defaultValue={item.rating.average / 2} />


})
}

)
}
}

改变导航

//通过编程式导航跳转到电影详情组件中去
goMovieDetail(movieId){
this.props.history.push(/movie/detail/${movieId})
}

//返回到上一级
goBack() {
this.props.history.goBack()
}

webpack打包

参考地址(性能优化):
https://doc.react-china.org/docs/optimizing-performance.html

webpack指南里面:
https://doc.webpack-china.org/guides/production/

1. 新建一个配置文件webpack_config_prod.js
2. 热重载要干掉
3. 压缩js
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
comments: false
})
4. 压缩html
参考网址:
https://github.com/jantimon/html-webpack-plugin
https://github.com/kangax/html-minifier#options-quick-reference

new HtmlWebpackPlugin({
template: './template.html',
filename: 'index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
minifyCSS: true,
minifyJS: true
}
})

5. output

const path = require('path');
output: {
path:path.resolve(__dirname, "dist"),
filename: "bundle.js"
}

6. 清除原先的dist
const CleanWebpackPlugin = require('clean-webpack-plugin');
new CleanWebpackPlugin(['dist'])

7. 配置package.json
"build": "webpack --progress --config webpack_config_prod.js"

优化打包:

抽离第三方包

1. 抽离图片
{
test: /.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 4000,//大于4kb就抽离出去
name:"images/[name]-[hash:5].[ext]"
}
}
]
}

2. 明确第三方库
https://doc.webpack-china.org/plugins/commons-chunk-plugin/

entry: {
quanjiatong:['react','react-dom','react-router-dom'],
fetchJsonp:['fetch-jsonp'],
bundle:'./src/main.js'
}
output: {
path:path.resolve(__dirname, "dist"),
filename: "js/[name].js"
}
new webpack.optimize.CommonsChunkPlugin({
name: ['quanjiatong','fetchJsonp'],
minChunks: Infinity,
})

3. 抽离对三方样式
https://github.com/webpack-contrib/extract-text-webpack-plugin

yarn add extract-text-webpack-plugin --dev

//抽离第三方样式的包
const ExtractTextPlugin = require("extract-text-webpack-plugin");

{
test: /.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: 'css-loader',
options: {
minimize: true //压缩css
}
}
]
})
}

new ExtractTextPlugin("styles.css"),

服务器反向代理

以后补充

posted on 2018-02-09 17:49  ouruixi  阅读(177)  评论(0)    收藏  举报

导航