React编写简书项目
这是看慕课网上的React课程做的总结笔记
MDN上的js教程 基础需打牢
重新介绍 JavaScript(JS 教程)
环境搭建
npm install -g create-react-app
create-react-app my-app
cd my-app
npm start
项目如果安装失败 具体请bing或者谷歌 又或者网络问题 可以设置npm淘宝源
npm config set registry https://registry.npm.taobao.org
-- 配置后可通过下面方式来验证是否成功
npm config get registry
项目运行成功
-
项目目录
项目目录
有两个文件要特殊提一下
- serviceWorker 断网后还可以访问
- index.js 入口文件
- public/manifest.json 这是个PWA应用 当成一个应用来使用 快捷方式在桌面上
- 把不需要的文件删除
编写Todolist
需提前了解
- styl语法
- 函数式编程
- ES6 箭头函数 结构赋值 类
- all in js jsx 语法糖
创建todolist.js 组件
index.js 入口文件引入 todolist组件
todolist组件代码
import React, { Component, Fragment } from 'react';
import './style.css';
class Todolist extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
list: ['学英语', '写代码', '把妹']
}
}
render() {
return (
<Fragment>
<div>
<label htmlFor="insert" style={{marginRight:20+'px'}}>输入内容</label>
<input id="insert" className="input" placeholder="请输入今日待办事项" value={this.state.inputValue} onChange={this.handleChange.bind(this)} />
<button onClick={this.handleClick.bind(this)}>submit</button>
</div>
{/*
如果需要在jsx里设置转义过后的 比如h1 标签 h2标签 span标签内容 就用到dangerouslySetInnerHTML
<ul>
{
this.state.list.map((item,index) =>{
return <li key={index} onClick={this.handleDelete.bind(this,index)} dangerouslySetInnerHTML={{__html: item}}></li>
})
}
</ul>
*/}
<ul>
{
this.state.list.map((item, index) => {
return <li key={index} onClick={this.handleDelete.bind(this, index)}>{item}</li>
})
}
</ul>
</Fragment>
)
}
handleChange(e) {
this.setState({
inputValue: e.target.value
})
}
handleClick(e) {
this.setState({
list: [...this.state.list, this.state.inputValue],
inputValue: ''
})
}
handleDelete(index) {
const _list = [...this.state.list]
console.log(index)
_list.splice(index, 1)
this.setState({
list: _list
})
}
}
export default Todolist;
创建style.css 并引入
注意以下几个问题
-
JSX语法
- 内联样式的写法
- jsx注释
- lable的for属性要写成htmlFor 不然会认为是for循环
- 注意constructor 要super(props) 然后声明状态
-
不能直接操作state
Immutable.js
组件拆分 组件传值
这章是重点
把Todolist里的每个事项拆分成子组件 方法如下
- 创建todolist-item组件
- 引入todolist-item
- 代码如下:
// todolist 父组件代码 调用部分 <Todoitem index={index} content={item} deleteitem={this.handleDelete.bind(this)} /> //todolist-item 组件代码 import React, { Component } from 'react'; class Todoitem extends Component { constructor(props){ super(props) this.handleDelete = this.handleDelete.bind(this) } render() { return ( <div onClick={this.handleDelete}> {this.props.content} </div> ); } handleDelete(){ console.log(this.props.index) this.props.deleteitem(this.props.index) } } export default Todoitem
-
注意以下几点
- 传值 父组件定义属性 子组件接受props 包括数据 方法等等都可以
- 尤其注意
this
因为绑定不正确会报没有找到某一个属性或者其他错误 - 子组件要调用父组件的方法 并改变父组件的数据 就用属性将方法传递过去 子组件props接受方法即可
父组件代码优化
import React, { Component, Fragment } from 'react';
import Todoitem from './todolist-Item';
import './style.css';
class Todolist extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
list: ['学英语', '写代码', '把妹']
}
// 页面一开始就绑定好方法this指向
this.handleClick= this.handleClick.bind(this)
this.handleDelete = this.handleDelete.bind(this)
this.handleChange = this.handleChange.bind(this)
}
render() {
return (
<Fragment>
<div>
<label htmlFor="insert" style={{marginRight:20+'px'}}>输入内容</label>
<input
id="insert"
className="input"
placeholder="请输入今日待办事项"
value={this.state.inputValue}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>submit</button>
</div>
<ul>{this.getTodoItem()}</ul>
</Fragment>
)
}
getTodoItem(){
return this.state.list.map((item, index) => {
return (
<Todoitem
key={index}
index={index}
content={item}
deleteitem={this.handleDelete}
/>
)
})
}
handleChange(e) {
const value = e.target.value
//setState 可以写方法 并且返回一个对象 对象变成函数 最外侧把要更改的值 保存一下
this.setState(
()=> ({inputValue : value})
)
// this.setState({
// inputValue: e.target.value
// })
}
handleClick(e) {
this.setState((prevState)=>({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
})
)
}
handleDelete(index) {
// const _list = [...this.state.list]
// console.log(index)
// _list.splice(index, 1)
// this.setState({
// list: _list
// })
this.setState(
(prevState)=>{
console.log(prevState)
const _list = [...prevState.list]
_list.splice(index, 1)
return { list : _list }
}
)
}
}
export default Todolist;
子组件代码优化
import React, { Component } from 'react';
class Todoitem extends Component {
constructor(props){
super(props)
this.handleDelete = this.handleDelete.bind(this)
}
render() {
const { content } = this.props
return (
<div onClick={this.handleDelete}>
{content}
</div>
);
}
handleDelete(){
console.log(this.props.index)
const { deleteitem,index } = this.props
deleteitem(index)
}
}
export default Todoitem
引发一些思考
我觉得这是听到最舒服的部分 带进自己的思考 才理解了React出现的原因 之前在学习vue的过程中并没有感受到 估计是之前比较木讷
-
声明式开发: 面向数据编程 类似于盖房之前把设计稿图纸画好 React会自动开始建造
-
与其他框架共同开发: 在我理解看来 比如项目中操作交互比较复杂的情况下可以用React来实现 页面其他部分保持不变就可以了
类似 购物车可以写成一个组件 页面其他部分继续用Jq来操作编写页面 等等 -
组件开发 首字母大写
-
父子组件传值 F:父组件 Z:子组件
F=>Z : F定义属性 Z用props接受
Z=>F : Z用F定义的方法 F把该方法传递给Z Z组件调用方法 间接操作F值 实现Z=>F 传值 -
单项数据流 Z可以使用F传来的值 但不能修改这个值 之所以单向我想了下 如果子组件特别多项目大 Z更改数据 会导致 其他组件接受到的数据也被更改 破坏了数据源
-
React视图层框架 它只负责数据渲染工作 不然也不会出现Redux Flux 这种做数据层框架做数据传递 处理
A->B做数据传递
-
函数式编程 非常容易做自动化测试等等
网友评论