class hello extend React.Compenent {
constrctor(props){
super(props)
this.inputElement = React.createRef()
}
render(){
return (
)
}
}
const hello = () => {
loading...
class ErrorBoundary extends React.Compenent {
constructor(props){
super(props)
this.errorState = false
}
static getDerivedStateFromError(error){
return { errorState: true }
}
componentDidCatch(error, errorInfo) {
// 你同样可以将错误日志上报给服务器
logErrorToMyService(error, errorInfo);
}
render(){
if(this.state.errorState){
return something went wrong
}
return this.props.children
}
}
// 然后作为一个常规组件使用它
const ThemeContext = React.createContext('light')
class App extends react.compenent {
render () {
return {
}
}
}
const Toolbar = () => {
return (
)
}
class ThemesButtons extends React.Compenent {
static contextType = ThemeContext;
render() {
return ;
}
}
function Page(props) {
const user = props.user;
const userLink = (
);
return ;
}
// 现在,我们有这样的组件:
// ... 渲染出 ...
// ... 渲染出 ...
// ... 渲染出 ...
{props.userLink}
const ref = React.createRef()
FancyButton>
const FancyButton = React.forwardRef((props, ref) => {
return (
)
})
console.log(ref.current) // 为button这个dom元素
class Columns extends React.Component {
render() {
return (
Hello
World
);
}
}
// 或者
class Columns extends React.Component {
render() {
return (
<>
Hello
World
>
);
}
}
key 是唯一可以传递给 Fragment 的属性。
function Glossary(props) {
return (
{props.items.map(item => (
// 没有`key`,React 会发出一个关键警告
- {item.term}
- {item.description}
))}
);
}
// CommentListWithSubscription 和 BlogPostWithSubscription具有相同业务逻辑,只是数据不同,那么通过withSubscription传入不同的数据即可。
const CommentListWithSubscription = withSubscription(
CommentList,
(DataSource) => DataSource.getComments()
);
const BlogPostWithSubscription = withSubscription(
BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id)
)
// 此函数接收一个组件...
function withSubscription(WrappedComponent, selectData) {
// ...并返回另一个组件...
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource, props)
};
}
componentDidMount() {
// ...负责订阅相关的操作...
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
this.setState({
data: selectData(DataSource, this.props)
});
}
render() {
// ... 并使用新数据渲染被包装的组件!
// 请注意,我们可能还会传递其他属性
return ;
}
};
}
// no no no
function logProps(InputComponent) {
InputComponent.prototype.componentDidUpdate = function(prevProps) {
console.log('Current props: ', this.props);
console.log('Previous props: ', prevProps);
};
// 返回原始的 input 组件,暗示它已经被修改。
return InputComponent;
}
// 每次调用 logProps 时,增强组件都会有 log 输出。
const EnhancedComponent = logProps(InputComponent);
// yes yes
function logProps(WrappedComponent) {
return class extends React.Component {
componentDidUpdate(prevProps) {
console.log('Current props: ', this.props);
console.log('Previous props: ', prevProps);
}
render() {
// 将 input 组件包装在容器中,而不对其进行修改。Good!
return ;
}
}
}
Click Me
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)
import React from 'react';
const MyComponents = {
DatePicker: function DatePicker(props) {
return Imagine a {props.color} datepicker here.;
}
}
function BlueDatePicker() {
return ;
}
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 错误!JSX 类型不能是一个表达式。
return ;
}
function Story(props) {
// 正确!JSX 类型可以是大写字母开头的变量。
const SpecificStory = components[props.storyType];
return ;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return ;
}
{msg}
function TodoList() {
const todos = ['finish doc', 'submit pr', 'nag dan to review'];
return (
{todos.map((message) => )}
);
}
function ListOfTenThings() {
return (
{(index) => This is item {index} in the list}
);
}
// 在 DOM 中有两个容器是兄弟级 (siblings)
const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root');
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
modalRoot.appendChild(this.el);
}
componentWillUnmount() {
modalRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {clicks: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
clicks: state.clicks + 1
}));
}
render() {
return (
Number of clicks: {this.state.clicks}
Open up the browser DevTools
to observe that the button
is not a child of the div
with the onClick handler.
);
}
}
function Child() {
// 这个按钮的点击事件会冒泡到父元素
// 因为这里没有定义 'onClick' 属性
return (
);
}
ReactDOM.render( , appRoot);