《深入浅出React和Redux》已近由机械工业出版社发行,这个repo存放的是书中所有的代码。
配合React和Redux的持续讨论,作者开通了一个知乎专栏《进击的React》,欢迎关注。对React和Redux技术有问题可以通过私信或者值乎咨询,有问必答。
京东(这个链接里有书的目录)
《深入浅出React和Redux》代码
《深入浅出React和Redux》已近由机械工业出版社发行,这个repo存放的是书中所有的代码。
配合React和Redux的持续讨论,作者开通了一个知乎专栏《进击的React》,欢迎关注。对React和Redux技术有问题可以通过私信或者值乎咨询,有问必答。
京东(这个链接里有书的目录)
很明显,无论我们有多少“小的” reducer,也无论如何组合,都不用在乎它们被因为调用的顺序,...
应修正为:“都不用在乎它们被调用的顺序,...”
export const addTodo = (text) => ({
type: ADD_TODO,
completed: false,
id: nextTodoId ++,
text: text
});
其中complted字段并不需要传递给reducer
因为在reducer中:
switch(action.type) {
case ADD_TODO: {
return [
{
id: action.id,
text: action.text,
completed: false
},
...state
]
}
...
可以看见,每新增一个todo,它的completed必为false,没有必要在action中传递,导致数据冗余。
请教作者一个问题(不算是issues,但是除了提issues,不知道还有什么联系方式了):关于第12章 同构说的:
如果应用没有使用代码分片,浏览器端的路由部分就无需任何改变,不过在我们的
例子中已经应用了代码分片,所以应用了服务器端渲染之后,浏览器端渲染也要做对应
修改,使用match函数来完成匹配,否则,服务器端和浏览器中产生的HTML会不一
致,这种不一致不是脱水数据问题导致,而是产生两端的代码不一致导致的。
这里我实在想不通,为什么不一致会导致html的不同,store数据一样,模版相同为什么要用match的方式?方便给解答下吗?
谢谢!
第六段 Dispatcher.register 写成了 Dispatcherregister。
最顶部的“如果第二个参数是函数类型,那就认为没有初始状态,直接把第三个参数当做增强器处理”应该是“如果第二个参数是函数类型,那就认为没有初始状态,直接把第二个参数当做增强器处理”
reducer.js 定义这个功能模块如何相应actions.js中定义的动作;
其中:相应 => 响应
第27页
Sample.defaultProps = { return { sampleProp: 0} };
应该是
Sample.defaultProps = { sampleProp: 0 };
第38页
倒数第二段最后,“如图2-6所示”
应该是,“如图2-7所示”
第50页
倒数第三段,“那就直接接续”
应该是,“那就直接继续”
第79页
4.3节第四段,“以我们将要实现实现...“
应该是,”以我们将要实现...“
页Control组件的当前值(子)组件的内部状态
const Sample = React.createClass({ ... return {sampleProp: 0} }) // 多了一个小括号 })
原文中第48页倒数第六行
最后都要调用outerStore.emitChange函数
应改为:最后都要调用CouterStore.emitChange函数
如果傻瓜组件只管渲染的话,那么那些非store中数据如何从容器组件传到傻瓜组件中呢
第 3 行
mapDispatch-ToProps
应为 mapDispatchToProps
P153 第 4 行中的 response.body 函数
应为 response.json 函数
。
以我们将要实现实现的Todo应用为例,
多了一个词:“实现”
react-router-v4有沒有chunk的方案呢?
代码验证,应该是
1. componentWillReceiveProps
2. shouldComponentUpdate
在书中,上述两个顺序反了。
比如 P46、P59。
// P46
const SummaryStore = Object.assign({}, EventEmitter.prototype, {
getSummary() {
return computeSummary(CounterStore.getCounterValues());
},
});
// P59
export const decrement = (counterCaption) => {
return {
type: ActionTypes.DECREMENT,
counterCaption
};
};
我的想法是:既然本书有涉及到 ES6 语法的代码,那么能够用 ES6 语法的地方就应该用尽量用。
虽然代码都能看懂,但是强迫症很难受啊。
用上 ESLint 会不会好点。
对于filter而言,在其子组件link里面有这样一段向store发起dispatch请求的代码:
const mapStateToProps = (state, ownProps) => {
return {
active: state.filter === ownProps.filter
}
};
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => {
dispatch(setFilter(ownProps.filter));
}
});
export default connect(mapStateToProps, mapDispatchToProps)(Link);
而对todoList的子组件todoItem而言,其dispatch逻辑被放在了todoList里面,然后以参数形式传入todoItem,哪种方法更好?如下:
const TodoList = ({todos, onToggleTodo, onRemoveTodo}) => {
return (
<ul className="todo-list">
{
todos.map((item) => (
<TodoItem
key={item.id}
text={item.text}
completed={item.completed}
onToggle={() => onToggleTodo(item.id)}
onRemove={() => onRemoveTodo(item.id)}
/>
))
}
</ul>
);
};
......
const mapDispatchToProps = (dispatch) => {
// TODO
// wh not inside todoItem, efficiency?
return {
onToggleTodo: (id) => {
dispatch(toggleTodo(id));
},
onRemoveTodo: (id) => {
dispatch(removeTodo(id));
}
};
以下代码,混用了中文的 “”
<span id=“ clickCount”>{this.state.count}</span>
page 121 中不加key运行时不会有warning。
<ul>
<Item />
<Item />
<Item />
</ul>
上述情况不加key尽管react 无法有效diff,但实际运行的时候不会报warning。
只有使用array map的时候不加key才会有warning。
关于componentWillReceiveProps函数的
p31的下半段
当点击强制刷新按钮后(即调用forceUpdate方法的按钮)
控制台输出了
enter ControlPanel render
enter componentWillReceiveProps First
enter render First
enter componentWillReceiveProps Second
enter render Second
enter componentWillReceiveProps Third
enter render Third
实际上只输出了
enter ControlPanel render
enter componentWillReceiveProps First
enter componentWillReceiveProps Second
enter componentWillReceiveProps Third
照我理解是因为组件state和props并没有发生改变,所以不会触发render函数
请问这是react版本的问题还是笔误?
感谢您的查看!书写的很好!非常感谢
引发这个组件实例的更新过程,也就是按照顺序引发下列函数:
应该是:
譬如在react-and-redux/chapter-02/controlpanel/src/Counter.js里
第43行至第45行
onClickIncrementButton() { this.setState({count: this.state.count + 1}); }
是否应该这样写
onClickIncrementButton() { this.setState(prevState => ({ count: ++prevState.count })); }
因为根据状态更新可能是异步
这一节的说法,在这种情况下使用prevState更好
所以此时该依赖prevState来更新state吗,还是直接如源码一样不使用prevState也可以?
第二个代码块里:
f(f); // 结果是 (3+4) * 5 = 37
计算错误
通过store.getState()总能够读取当整个状态树的数据
多了个 “当”,应修正为:“通过store.getState()总能够读取整个状态树的数据”
請問有react-i18n根據語言和路由按需按加载方案嗎
81页第7行:
import TodoListComponents from './actions.js'
我想应该是
import TodoListComponents from '../todoList';
那部分看得不太懂,去查了一下export 和 export default的区别,顺便贴出来给跟我一样不太明白的朋友看一下:
export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。
即:
import { default as xxx } from 'modules';
等同于
import xxx from 'modules';
以下代码中入参onClick是从哪里传入?是不是对应了else逻辑里面的onClick()?是不是也对应了mapDispatchToProps里面的onClick?
const Link = ({active, children, onClick}) => {
if (active) {
return <b className="filter selected">{children}</b>;
} else {
return (
<a href="#" className="filter not-selected" onClick={(ev) => {
ev.preventDefault();
onClick();
}}>
{children}
</a>
);
}
};
......
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => {
dispatch(setFilter(ownProps.filter));
}
});
Summary 在这里应该为一个无状态组件了, 不存在 state , 应为 props
在 Summary.js
中第5行
const sum = this.state.sum;
应改为
const sum = this.props.sum;
还有一种惯常写法,就是把解构赋值(destructuring assignment)直接放在参数部分。
function Counter ({caption, onIncrement, onDecrement, value} { //函数体中可以直接使用caption、onIncrement等变量 }
代码中函数定义部分少了闭合的小括号:
function Counter ({caption, onIncrement, onDecrement, value}) {
应该是 “ 如图2-7 所示 ”。
请教博主,您的源码中是怎么使用webpackage,具体用的是什么样的命令?
从代码的角度出发,深层次树形状态状态结构会让代码冗长。
多了一个词:“状态”
首先counter的state由prop而来, 最佳实践中不推荐这么做
https://github.com/planningcenter/react-patterns#setting-state-from-props这里有说明, 官方也有
加法/减法的function不是应该放到父组件吗?
不是推荐pure component吗? 为什么子组件还要弄个state, 这个和Thinking in React这篇文章是背道而驰的
请作者给出一个解释
第二章 设计高质量的 React 组件 P27
示例代码:
Sample.defaultProps = {
return { sampleProp: 0 }
}
defaultProps 中应该为键值对,所以 return 应该去掉,正确格式:
Sample.defaultProps = {
sampleProp: 0
}
谢谢。
全局变量nextSeqId=0,局部变量seqId = ++nextSeqId;
第一次点击之后两个都为1,这时候走dispatch(),第二次点击的时候nextSeqId被赋值2,seqId也是2啊,即使在数据没有返回之前点击,这种写法也应该还是相等的,我不明白怎么就能不相等中止异步了?望解惑,谢谢
我觉得高内聚是指模块内部高度聚合,功能专一,“把逻辑相关的内容放在一个组件中”并不准确。
该段的例子,把一个功能的css,js放在多个文件中,并没有违背高内聚,因为对于单个css来说,它是功能单一的。
个人浅见
windows环境下,npm start:isomorphic 会报错‘NODE_ENV’不是内部变量
解决:
添加npm install --save cross-env
将packjson修改为:"start:isomorphic": "cross-env NODE_ENV=development node server/index.js"
解决问题。
进入127.0.0.1:9000,然后点击counter,会报fetch跨域错误。
解决:
修改app.dev.js代码
app.use('/api/count', (req, res) => {
res.header("Access-Control-Allow-Origin", "*"); // 添加这行
res.json({count: 100});
});
当时(然)读取了修改过的值
chapter-03/react-redux - npm start后网页中有Warning怎么解决,新手不会调错,麻烦告诉下怎么解决。
还有打包文件的时候,访问打包生成的index.html也有报错,这个怎么解决呀?
麻烦告诉一下,谢谢
正在入门的菜鸟.
f(g) 结果应该是 (3 + 4) + 5 = 12
完成优化之后也无法知道性能优化是否到了预期的结果
其中 “是否到了预期的结果” 修正为 “是否达到了预期的结果”
我购买了电子版的纸版的,是个好读者吧:)
我发现这些例子在我的机器上都无法运行,比如进入任意一个例子目录下,以react-and-redux\chapter-03\react-redux为例,运行: npm start 后会出现如下错误:
`Error: Cannot find module 'dotenv'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object. (C:\dev\react\react-and-redux\chapter-03\redux_smart_dumb\scripts\start.js:7:1)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\dev\tools\nodejs\node.exe" "C:\dev\tools\nodejs\node_modules\npm\bin\npm-cli.js" "start"
npm ERR! node v6.10.3
npm ERR! npm v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: node scripts/start.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node scripts/start.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the demo package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node scripts/start.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs demo
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls demo
npm ERR! There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! Please include the following file with any support request:
npm ERR! C:\dev\react\react-and-redux\chapter-03\redux_smart_dumb\npm-debug.log
C:\dev\react\react-and-redux\chapter-03\redux_smart_dumb>`
然后我运行: npm install -g dotenv
再运行: npm start
错误还是和开始时相同,我启动的方式不对吗?请给我一点提示吧, 谢谢了!
你好,刚购买了你的书籍,我是个新手,
根据目前的理解,
感觉chapter-04/todo里的constructor 只要传入props即可,
因为 已经用上了redux,
用Provider把store传递给了组件, 那么这里的context是否就可以删除了?
看到代码多出了个context有点懵,因为感觉好像并没有用到
https://github.com/mocheng/react-and-redux/blob/master/chapter-04/todo/src/todos/views/addTodo.js#L8
时间(事件)处理器
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.