背景: 3月份离职了,之后入职新公司,第一个任务是react + ts + node项目;由于没有react开发经验就先过了一遍文档,在开始敲代码的时候总是会忘记语法,然后就做了个react 基础语法和注意事项 相关的文档,加一些和vue使用的区别,有react经验的小伙伴就不需要浪费时间往下看啦~~
那么就开始吧~
- 变量作为属性值及模版中嵌入表达式
<!--react-->
<span type={user.type}>{user.name}</span>
<!--vue-->
<span :type="user.type">{{user.name}}</span>
单向数据流
react 通过setState
来修改,方便定位问题;
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改
vue也是单向数据流不过也还是可以通过黑科技改变props的模版嵌套
组件的嵌套设计,复杂大型功能自下而上,小型功能自上而下,方便处理和测试react 的 state
组件私有属性,用与子组件共享,用于可变状态(mutable state);
react如果子组件共用且均需要修改state时要将state提升到公共父级去,修改需使用setState来处理最小state
通过父级props传进来;随着时间的推移保持不变;能根据其他props和state技术出来;
以上3种情况都不应该另用新state-
组件不使用state时可写成函数形式
function LogoutButton(props) { return ( <button onClick={props.onClick}> Logout </button> ); } <!--组件使用--> <LogoutButton />
反向数据流
子组件通知父组件修改state,通过调用回调函数来解决,将父组件函数传入子组件来进行处理;不同于vue是子组件emit事件,父级接收到emit来执行相关函数-
阻止默认事件
不能通过返回false
的方式阻止默认行为。你必须显式的使用preventDefault
<!--无法阻止--> <a href="#" onclick="console.log('The link was clicked.'); return false"> Click me </a>
<!--正确做法--> function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); }
组件名开头必须大写
React 会将以小写字母开头的组件视为原生 DOM 标签。 <div> 代表 HTML 的 div 标签,而 <Welcome />则代表一个组件,并且需在作用域内使用 Welcome。规范详见深入JSXstyle
在模板上直接使用要用‘双括号’
定义style对象添加
<!--直接在模版添加-->
<div
className="board-row"
style={{color: 'red'}}
>喂喂,testtest</div>
<!--style变量-->
const devClass = {color:red};
<div style={ devClass, ..., ....}></div>
<!--如果是font-size等有中线的要改为驼峰-->
<div style={{fontSize:'14px'}} key={item.title}>
-
class
在react中class是保留字因此以className
替换,其他差异详见react属性差异function Square(props) { return ( <button className="square" onClick={props.onClick}> {props.value} </button> ); }
-
对比于 vue slot
- react 子组件通过
props.children
可以实现;比起slot props
可以传递任何东西
function FancyBorder(props) { return ( <div> <!--如果父级传入children将会被覆盖--> {props.children} </div> ); } function WelcomeDialog() { return ( <!--此处children不会被接收,会被子组件所覆盖--> <FancyBorder color="blue" children={11}> <h1 className="Dialog-title"> Welcome </h1> </FancyBorder> ); } ReactDOM.render( <WelcomeDialog />, document.getElementById('root') );
- 父组件直接将组件传入及子组件
props[any]
获取
- react 子组件通过
-
fragment
render return时需要包裹dom元素;
React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点render() { return ( <React.Fragment> <ChildA /> <ChildB /> <ChildC /> </React.Fragment> ); }
你可以使用一种新的,且更简短的语法来声明 Fragments;可以像使用任何其他元素一样使用
<>
</>
,除了它不支持 key 或属性class Columns extends React.Component { render() { return ( <> <td>Hello</td> <td>World</td> </> ); } }
-
参数传递,详见Context
- context:设计目的是为了共享那些对于一个组件树而言是“全局”的数据;主要应用场景在于很多不同层级的组件需要访问同样一些的数据;
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。 // 为当前的 theme 创建一个 context(“light”为默认值)。 const ThemeContext = React.createContext('light'); class App extends React.Component { render() { // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。 // 无论多深,任何组件都能读取这个值。 // 在这个例子中,我们将 “dark” 作为当前的值传递下去。 return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } } // 中间的组件再也不必指明往下传递 theme 了。 function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } class ThemedButton extends React.Component { // 指定 contextType 读取当前的 theme context。 // React 会往上找到最近的 theme Provider,然后使用它的值。 // 在这个例子中,当前的 theme 值为 “dark”。 static contextType = ThemeContext; render() { return <Button theme={this.context} />; } }
- 组件组合(将组件传入)
<!--原--> <Page user={user} avatarSize={avatarSize} /> // ... 渲染出 ... <PageLayout user={user} avatarSize={avatarSize} /> // ... 渲染出 ... <NavigationBar user={user} avatarSize={avatarSize} /> // ... 渲染出 ... <Link href={user.permalink}> <Avatar user={user} size={avatarSize} /> </Link> <!--改:只有最顶部的 Page 组件需要知道 Link 和 Avatar 组件是如何使用 user 和 avatarSize 的。--> function Page(props) { const user = props.user; const userLink = ( <Link href={user.permalink}> <Avatar user={user} size={props.avatarSize} /> </Link> ); return <PageLayout userLink={userLink} />; } // 现在,我们有这样的组件: <Page user={user} avatarSize={avatarSize} /> // ... 渲染出 ... <PageLayout userLink={...} /> // ... 渲染出 ... <NavigationBar userLink={...} /> // ... 渲染出 ... {props.userLink}
错误边界
部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了该概念;
错误边界是一种 React 组件,这种组件可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且它会渲染出备用 UI,而不是渲染那些崩溃了的子组件树。错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误
- 组件首字母必须大写
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 错误!!!!JSX 类型不能是一个表达式。
return <components[props.storyType] story={props.story} />;
// 正确!!!!JSX 类型可以是大写字母开头的变量。
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
- 传递子集动态变量(直接传就行) 在此基础上改
render() {
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
const tmp = [
{scale: 'c', key: celsius},
{scale: 'f', key: fahrenheit},
]
return (
<div>
{
tmp.map(item => {
return <TemperatureInput
scale={item.scale}
temperature={item.key}
onTemperatureChange={this.handelCommon}
/>
})
}
</div>
);
}
- 传递当前event
<!--react-->
<input
type="text"
placeholder="Search..."
value={this.props.filterText}
onChange={(e)=>this.handleFilterTextChange('sth', e)}
/>
<!--vue-->
<searchInput
v-model="params.nameKey"
placeholder="搜索名称"
icon="android-close"
@search="searchData"
@clear="afterChange('nameKey', $event)"
></searchInput>
- Portal 弹窗🌰
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。
典型用例是当父组件有 overflow: hidden 或 z-index 样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框
19.componentWillReceiveProps
使用时最好比较两个props一面陷入死循环,不停更新组件参考
等等。。。
参考:
结语:
有咩有小伙伴能提供个更恰当的文章名字哇。。。嘤嘤。。起名废