《react学习之道》---阅读笔记
安装
1.https://www.bookstack.cn/read/the-road-to-learn-react-chinese/manuscript-chapter1-cn.md
不用先npm init -y(因为框架里边已经搭建好了)
npm install -g create-react-app
create-react-app hackernews
入口文件
用于测试的 src/App.test.js 和作为 React 世界的入口的 src/index.js
控制你项目整体样式和组件样式的 src/index.css 文件和 src/App.css 文件,他们都被设置成了默认的样式。
启动
// 在 http://localhost:3000 启动应用
npm start
// 运行所有测试
npm test
// 构建项目的产品文件
npm run build
var const let 用法
我的建议是在任何你可以使用 const 的时候使用它。
这表示尽管对象和数组的内容是可以被修改的,你仍希望保持该数据结构不可变。
而如果你想要改变你的变量,就使用 let 去声明它。
入口文件index.js 中ReactDOM.render() 作用
ReactDOM.render() 会使用你的 JSX 来替换你的HTML中的一个 DOM 节点;
在一个纯 React 的应用中,你只会使用一次用来加载你的整个组件树。
ReactDOM.render() 有两个传入参数。
第一个是准备渲染的 JSX。
第二个参数指定了React应用在你的HTML中的放置的位置。
这个位置是一个 id='root'的元素。你可以在文件 public/index.html 中找到这个id属性。
最新的react-app框架集成了热更新
--不用再去配置下面的代码--
if (module.hot) {
module.hot.accept();
}
创建的项目有一个优点,那就是可以让你在更改源代码的时候浏览器自动刷新页面
dom使用map循环遍历数组
注意:要声明一个标识符
1.声明
const list = [
{
title: 'React',
url: 'https://facebook.github.io/react/',
author: 'Jordan Walke',
num_comments: 3,
points: 4,
objectID: 0,
},
{
title: 'Redux',
url: 'https://github.com/reactjs/redux',
author: 'Dan Abramov, Andrew Clark',
num_comments: 2,
points: 5,
objectID: 1,
},
];
2.使用
或者
箭头函数
this指向不同:
你需要注意它的一些功能性。其中之一就是关于 this 对象的不同行为。一个普通的函数表达式总会定义它自己的 this 对象。但是箭头函数表达式仍然会使用包含它的语境下的 this 对象。不要被这种箭头函数的 this 对象困惑了。
{list.map(item => {
return();
})}
或者直接页可以省略掉return()
React 混合使用了两种编程范式中的有益的部分
1.面向对象编程
--声明类
Developer 类
class Developer {
constructor(firstname,lastname){
this.firstname = firstname;
this.lastname = lastname;
}
getName(){
retuen this.firstname+ '' +this.lastname;
}
}
--实例化这个类
const robin = new Developer('Robin','chishi');
console.log(robin.getName());
--继承一个类
component组件类
render()方法手机必须重写的方法
class App extends Component {
render() {
...
}
}
2.函数式编程
组件内部状态--单向数据流
1.在constructor(){}中定义变量和方法
2.改变constructor中的变量要是用setState()
原理:
你在界面通过 onClick 触发一个动作,再通过函数或类方法修改组件的 state,最后组件的 render() 方法再次运行并更新界面。
--- 声明方法一
constructor() {
super();
this.onClickMe = this.onClickMe.bind(this);
}
疑问:为什么一开始就要绑定 this.onDismiss = this.onDismiss.bind(this);
因为类方法不会自动绑定 this 到实例上;
你会在开发调试控制台中得到 undefined 。
这是使用 React 主要的 bug 来源,因为当你想在类方法中访问 this.state 时,由于 this 是 undefined 所以并不能被检索到。所以为了确保 this 在类方法中是可访问的,你需要将 this 绑定到类方法上。
--- 声明方法二
类方法的绑定也可以写起其他地方,比如写在 render() 函数中。
但是你应该避免这样做,因为它会在每次 render() 方法执行时绑定类方法
onClick={this.onClickMe.bind(this)};
注意:
另外有一些人们提出在构造函数中定义业务逻辑类方法。
this.onClickMe = () => {
console.log(this);
}
你同样也应该避免这样,因为随着时间的推移它会让你的构造函数变得混乱。构造函数目的只是实例化你的类以及所有的属性。这就是为什么我们应该把业务逻辑应该定义在构造函数之外。
------声明方法三
最后值得一提的是类方法可以通过 ES6 的箭头函数做到自动地绑定。
onClickMe = () => {
console.log(this);
}
如果在构造函数中的重复绑定对你有所困扰,你可以使用这种方式代替。React 的官方文档中坚持在构造函数中绑定类方法,所以本书也会采用同样的方式。
事件处理
构造函数和箭头函数的区别:
onClick={() => this.onDismiss(item.objectID)} // 不会立即执行,点击事件才会触发执行
onClick={this.onDismiss(item.objectID)} // 页面渲染的时候会立即执行,点击事件不会
搜索过滤
---原理---
当状态变化时,render() 方法将再次运行,并使用最新状态中的searchTerm 值来作为过滤条件
{/* 过滤 */}
{this.state.list.filter(isSearched(this.state.searchTerm)).map(item =>
----方法----
// 1.定义在 App 组件外定义一个高阶函数(一个函数返回另一个函数)
function isSearched(searchTerm) {
// 只有满足匹配时才会返回 true 并将项目保留在列表中
return function(item) {
return item.title.toLowerCase().includes(searchTerm.toLowerCase()); // toLowerCase方法用于把字符串转换为小写
}
}
/* es6写法
const isSearched = searchTerm => item =>
item.title.toLowerCase().includes
*/