React常见的15个问题 (2)

请注意,有时 Web 服务器可能在后台运行或在分离的屏幕/tmux 会话中运行。你看不到,但它仍然占据了端口。 要重新启动服务器,需要“杀死”仍在运行的服务器。

要识别使用某个端口的进程,可以使用 ps 之类的命令(以及关于应用程序的grep),或者如果你知道端口号,则可以使用 lsof 命令:

lsof -i :8080 8. 忘记创建环境变量

有些项目依赖于 shell 环境变量的存在才能启动。 如果在没有所需环境变量的情况下运行这些项目,它们将尝试为它们使用未定义的值,并可能会给你一些神秘的错误。

例如,如果项目连接到像 MongoDB 这样的数据库,则可能会使用像 process.env.MONGO_URI这样的环境变量来连接它。 这允许项目与不同环境中的不同MongoDB 实例一起使用。

要在本地运行连接到 MongoDB 的项目,首先必须导出 MONGO_URI 环境变量。 例如,如果你在端口 27017 上运行本地 MongoDB,则需要在运行项目之前执行此操作:

export MONGO_URI="mongodb://localhost:27017/mydb"

你可以 grep 项目源代码,找到 process.env 来查清楚其运行正常所需要的环境变量。

9. 把花括号{}和圆括号()搞混

不要用:

return { something(); };

这样用:

return ( something(); );

第一个将尝试(并且会失败)返回一个对象,而第二个将正确调用 something() 函数并返回该函数返回的内容。

因为 JSX 中的任何 <tag> 都将转换为函数调用,所以在返回任何 JSX 时都会出现这个问题。

这个问题在箭头函数的缩写语法中也很常见。

不要用:

const Greeting = () => { <div> Hello World </div> };

这样用:

const Greeting = () => ( <div> Hello World </div> );

当你使用带有箭头函数的中括号时,你就新起了一个函数的作用域。箭头函数的缩写语法不用中括号。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

10. 不使用圆括号包装对象

当你想要创建一个返回普通对象的箭头函数时,上面的花括号和圆括号问题也会让你感到困惑。

不要用:

const myAction = () => { type: 'DO_THIS' };

这样用:

const myAction = () => ({ type: 'DO_THIS'});

如果没有把对象包裹在圆括号里,你就不能使用缩写语法。实际上你会给字符串定义一个标签。

这在 setState 方法的 updater 函数中很常见,因为它需要返回一个对象。 如果要使用箭头函数语法,则需要用括号包装该对象。

不要用:

this.setState(prevState => { answer: 42 });

这样用:

this.setState(prevState => ({ answer: 42 })); 11. 没有正确使用API元素和属性的大小写

使用 React.Component,而不是 React.component。 使用 componentDidMount,而不是 ComponentDidMount。使用 ReactDOM,而不是ReactDom。

请注意需要的 API 大小写。 如果使用不正确的大小写,得到的错误信息可能不会很明确。

从 react 和 react-dom 导入时,确保引入正确的名称,并且使用的内容与引入完全相同,ESLint 可以帮助你指出未使用的内容。

在处理组件属性时也会遇到这种问题:

<Greeting userName="Max" /> // 在组件内部,你需要使用 props.userName 来获取传入的值

如果你没有使用 props.userName,而是 props.username 或 props.UserName,你会相当于用了一个 undefined 的值。需要特别留意下这点,当然更好的是配置 ESLint,它也能指出这些问题。

12. 将 state 对象与实例属性搞混

在类组件中,可以定义本地 state 对象,然后使用 this 访问它:

class Greeting extends React.Component { state = { name: "World", }; render() { return `Hello ${this.state.name}`; } }

以上代码会输出 “Hello World”。

除 state 之外,你还可以定义其它本地实例属性。

class Greeting extends React.Component { user = { name: "World", }; render() { return `Hello ${this.user.name}`; } }

以上代码也会输出 “Hello World”。

state 实例属性是一个特殊属性,因为 React 会管理它。 你只能通过 setState 更改它,当你这样做时 React 会做出响应。

然而,定义的所有其他实例属性对渲染算法没有影响。 你可以根据需要在上面的示例中更改this.user,并且 React 不会在React中触发渲染机制。

13. 将

在闭合标签里放错 / 字符。不可否认,有时你可以使用 <tag/>,而其他时间你需要</tag>。

在 HTML 中,有一种称为“自闭合标签”(AKA void tag)。这些是表示没有任何子节点的元素的标记。例如,img 标签是一个自闭合标签:

<img src="http://www.likecs.com/..." /> // 不必使用 <img></img>

div标签可以包含子项,因此你可以使用开始和结束标记:

<div> Children here... </div>

这同样适用于 Reac t组件,如果组件具有子元素,如下所示:

<Greeting>Hello!</Greeting> // 注意/字符的位置

如果组件没有子元素,可以用开始/结束标签书写,或者用自闭合标签:

// 两种方式 <Greeting></Greeting> <Greeting />

以下方式是非法的:

// 错误 <Greeting><Greeting />

如果放错放了 / 字符的位置,将收到如下错误:

Syntax error: Unterminated JSX contents 14. 假设 import/export 起作用

import/export 特性是 JavaScript 中的官方功能(自2015年起)。 其只是 ES2015 的特性,并且还没有在流行浏览器和最新版 Node 里面被完整支持。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwjys.html