1.render函数中return如果没有使用()会有什么问题?(jsx)
如果返回的是单行的元素,那么没有使用()不会有任何问题;
如果返回的是多行元素标签,标签没有换行那么也没有问题;
如果返回的是多行元素标签且换行了,那么会报错,错误的原因是jsx编译成js时会在每一行添加;,所以变 成了return;。
下面是babel的playground示例,preset预设选择es6和react。
class App extends React.Component {render() {return // 多行元素且换行<div><span>123</span></div>}}// babel解析结果:// ... 省略n多代码_createClass(App, [{key: "render",value: function render() {return; //React.createElement("div", null, React.createElement("span", null, "123"));}}]);// ... 省略n多代码
class App extends React.Component {render() {return <div> // 多行元素但是不换行<span>123</span></div>}}// babel解析结果:function (_React$Component) {_inherits(App, _React$Component);function App() {_classCallCheck(this, App);return _possibleConstructorReturn(this, _getPrototypeOf(App).apply(this, arguments));}_createClass(App, [{key: "render",value: function render() {return React.createElement("div", null, React.createElement("span", null, "123"));}}]);return App;}(React.Component);
class App extends React.Component {
render() {
return <div>123</div>
}
}
// babel解析结果:
var App =
/*#__PURE__*/
function (_React$Component) {
_inherits(App, _React$Component);
function App() {
_classCallCheck(this, App);
return _possibleConstructorReturn(this, _getPrototypeOf(App).apply(this, arguments));
}
_createClass(App, [{
key: "render",
value: function render() {
return React.createElement("div", null, "123");
}
}]);
return App;
}(React.Component);
2.componentWillUpdate可以直接修改state值吗?(生命周期)
当组件收到新的props或者state时,会在渲染之前调用componentWillUpdate(),使用此作为在更新发生之前执行准备更新的机会,初始渲染时不会调用这个方法。
你不能在这个方法中调用this.setState(),会触发重复循环。在componentWillUpdate()返回之前,你也不应该执行任何其他的操作触发对eact组件的更新。—来自react官网—
3.说说你对React的渲染原理的理解(渲染原理)
React使用JSX,可以使用在JS中写HTML标签,然后ES6的写法babel把JSX解析成虚拟DOM,es5的话使用React.createElement方法创建虚拟DOM,把虚拟DOM挂载到真实的DOM节点上。React组件会执行React.Component的钩子函数,组件内的状态值通过setState方法进行改变,然后触发render()函数进行渲染,这个过程中React会使用diff算法与之前的虚拟DOM树进行比较,只渲染之前改动的节点。(表达的不好QAQ)
JSX代码经过babel编译之后变成React.createElement的表达式,这个表达式在render函数被调用的时候执行生成一个element。
在首次渲染的时候,先去按照规则初始化element,接着ReactComponentComponentWrapper通过递归,最终调用ReactDOMComponent的mountComponent方法来帮助生成真实DOM节点。
4.什么是渲染劫持?(高阶函数)
通过高阶组件反向继承所传入的组件,然后控制wrappedComponent组件的渲染结果,并且可以做各种操作
1 读取、添加、修改、删除任何一个将被渲染的React Element的props 2 在渲染方法中读取或更改React Elements tree(WrappedComponent children) 3 根据条件不同,选择性的渲染子树 4 给子树里的元素变更样式
条件渲染:
function iiHOC(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
if (this.props.loggedIn) {
return super.render()
} else {
return null
}
}
}
}
通过 render 来变成 React Elements tree 的结果
function iiHOC(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
const elementsTree = super.render()
let newProps = {};
if (elementsTree && elementsTree.type === 'input') {
newProps = {value: 'may the force be with you'}
}
const props = Object.assign({}, elementsTree.props, newProps)
const newElementsTree = React.cloneElement(elementsTree, props, elementsTree.props.children)
return newElementsTree
}
}
}
5.说说Context有哪些属性
childContextTypes, contextTypes
6.怎么使用Context开发组件
参考:聊一聊我对 React Context 的理解以及应用
7. 为什么React并不推荐我们优先考虑使用Context(v16之前的版本)
绝大多数的应用不需要直接使用Context。
如果你希望你的应用是稳定的,那么就不要使用Context。 因为这是一个实验性质的API,它可能会在未来的React版本中移除。
如果你不熟悉state管理库如Redux或MobX,不要使用Context。 对于许多实际的应用,这些state管理库和React一起使用来管理那些与组件相关的state一个很不错的选择。 很多情况下使用Redux就可以解决你的问题,而不是使用Context。
如果你不是一个有经验的React开发人员,不要使用Context。 使用props和state来实现功能是一个更好的方法。
尽管有上面这些警告你还坚持使用Context,那么请将Context单独隔离到一个小区域中,并尽可能地避免直接使用Context,以便在这个API更改时应用能更容易升级。
8.除了实例的属性可以获取Context外哪些地方还能直接获取Context呢
组件的构造方法:
constructor(props,context)
生命周期:
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componetWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)
函数组件:
function Welcome(props, context) {
return (<div>{this.props}</div>)
}
9.childContextTypes是什么?它有什么用
Context提供者通过childContextTypes定义传递的数据参数,可以像propTypes一样定义数据类型,getChildContext传递数据的值。Context生产者,需要通过一个静态属性childContextTypes声明提供给子组件的Context对象的属性,并实现一个实例getChildContext方法,返回一个代表Context的纯对象 (plain object) 。
import React from 'react';
import PropsTypes from 'prop-types';
class Parent extends React.Component {
static childContextTypes = {
color: PropTypes.string.isRequired,
}
getChildContext() {
return {
color: 'red',
}
}
render() {
// ...
}
}
class ChildComp extends React.Component {
static contextTypes = {
color: PropTypes.string.isRequired,
}
render() {
const color = this.context.color;
}
}
10.contextType是什么?它有什么用
子组件需要通过一个静态属性contextTypes声明后,才能访问父组件Context对象的属性,否则,即使属性名没写错,拿到的对象也是undefined。
