正文
- _jsx 创建的只是一个简单的对象,并不是
DOM
节点,所以它没有appendChild
方法供我们调用。
const div = <div /> div.appendChild("input")
- JSX 和 HTML 两种标记语言不一样的根源是因为 JSX 就是 JavaScript 代码,要遵循 JavaScript 代码规则。当然,我们还可以把 JSX 看成增强型的 HTML,因为支持自定义标签等高级功能。
- 组件元素返回的是 React 元素,其实就是一个 JavaScript 对象,并不是 DOM 元素。
- 只要是表达式就可以放到 JSX 的大括号里,因为 JSX 实际上就是 JavaScript 代码,大括号内的表达式也将被作为 JavaScript 执行。
- 当大括号内的表达式为数组时,JSX 会把数组内容解释为标签的“孩子”。这样,当数据以数组的形式存在时我们能够轻易地将其转换为响应的 JSX 标签。
- key 最佳选项是数据里本来就存在的 id,
<select> {snacks.map((snack) => ( <option key={snack.id} value={snack.id}></option> )) } </select>
- 因为
State
里的数据是不可变的。React 只要看到还是同一个数组,就会认为 State 没有发生任何变化。即使你非要直接修改数组,React 也会置之不理,不会更新用户界面。确切地说,这是 React 与所有程序员的一个约定:State 内的数据、Prop 和 React 元素都是不可变的。之所以只是一个约定,是因为在 JavaScript 中没有办法将数组强制设置为不可变,所以对这个约定遵守与否,革命还得靠自觉(后果也得自负)。
- 无论 State 中的是数组还是对象,我们要刷新的话,就必须重建一个新的数组或对象,不能直接在原有的数组或对象的基础上修改。所以,在调用数组或对象方法时,也必须注意该方法是返回新的实例,还是在原有的实例上修改,例如,
Array.slice
返回一个新的数组,而Array.sort
则会在原地修改该数组。
- 为什么要不可变?就单次来说,重建确实比直接修改慢,但从总体上来说,这种采用重建来修改状态的机制性能更优。为什么直接修改微观上快,宏观上慢呢?这是因为,在绝大多数的用户界面里,最频繁的操作不是对程序状态的修改,而是对状态数据的读取比对。如果我们约定所有的状态数据值都是不可变的,那么对其的比对操作的性能就会有至少一个数量级的提升。
- 如果整个界面和程序状态大致不变、而需要非常频繁地读取和比对系统的状态,例如绝大部分的 Web 应用界面,用 React 就对了。这是因为 React 采用了不可变约定和浅层比较,是为数组读取操作而优化的。