Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于react无状态组件(函数式组件) #20

Open
ckinmind opened this issue Jan 12, 2017 · 8 comments
Open

关于react无状态组件(函数式组件) #20

ckinmind opened this issue Jan 12, 2017 · 8 comments

Comments

@ckinmind
Copy link
Owner

ckinmind commented Jan 12, 2017

参考资料1:掌握这5大核心概念,你就理解了React

参考资料2:React 中函数式声明组件

@ckinmind ckinmind changed the title 关于react无状态组件 关于react无状态组件(函数式组件) Jan 12, 2017
@ckinmind
Copy link
Owner Author

函数式组件与基于Class声明的组件相比,其具有以下特性

  • 不需要声明类,可以避免大量的譬如extends或者constructor这样的代码
  • 不需要显示声明this关键字,在ES6的类声明中往往需要将函数的this关键字绑定到当前作用域,而因为函数式声明的特性,我们不需要再强制绑定

写法:

//es5
class Text extends React.Component {
  render() {
    return <p>{this.props.children}</p>;
  }
}

//函数式声明组件
const Text = (props) =>
  <p>{props.children}</p>;

函数式声明组件可以不用绑定this

这种无状态函数式组件的写法也是支持设置默认的Props类型与值的

const Text = ({ children }) => 
  <p>{children}</p>
Text.propTypes = { children: React.PropTypes.string };
Text.defaultProps = { children: 'Hello World!' };

另外,在无状态的组件函数中,我们也是可以访问Context的

const Text = (props, context) =>
  <p style={context}>props.children</p>;
Text.contextTypes = {
  fontFamily: React.PropTypes.string
};
class App extends React.Component {
  static childContextTypes = {
    fontFamily: React.PropTypes.string
  }
  getChildContext() {
    return {
      fontFamily: 'Helvetica Neue'
    };
  }
  render() {
    return <Text>Hello World</Text>;
  }
}

@ckinmind
Copy link
Owner Author

ckinmind commented Jan 18, 2017

例子1:
改写前:

class ReactFormLabel extends React.Component {
    constructor() {
        super();
    }
    render() {
        return(
            <label htmlFor={this.props.htmlFor}>{this.props.title}</label>
        )
    }
}

改写后:

const ReactFormLabel = (props) =>(
    <label htmlFor={props.htmlFor}>{props.title}</label>
);

单行的括号可以省略

const ReactFormLabel = (props) => 
    <label htmlFor={props.htmlFor}>{props.title}</label>;
  1. this可以省略
  2. 注意label的for标签要写成htmlFor

通过对象的解构赋值,还可以写成这样

const ReactFormLabel = ({ htmlFor, title }) =>
    <label htmlFor={htmlFor}>{title}</label>;

无状态组件也是支持设置默认的Props类型与值

const ReactFormLabel = (props) =>
    <label htmlFor={props.htmlFor}>{props.title}</label>;

ReactFormLabel.propTypes = {
    title: React.PropTypes.string,
    htmlFor: React.PropTypes.string
};

@ckinmind
Copy link
Owner Author

看到一句话我们会使用函数式无状态组件除非需要本地 state 或生命周期函数的场景

这句话透露出什么状况下适合使用函数式组件:

  1. 无需state, 即不处理用户的输入,组件的所有的数据都是依赖props传入的
  2. 不需要用到生命周期函数

@yunshuipiao
Copy link

@ckinmind 那如果使用redux和mobx呢?

@ckinmind
Copy link
Owner Author

@yunshuipiao redux和无状态组件没关系, 至于mobx中无状态组件的写法参照这里

@yunshuipiao
Copy link

@ckinmind 上面说需要本地 state是一种什么样的情况。
此时的state改变是否可以用redux或者mobx来达到同样的效果?

@ckinmind
Copy link
Owner Author

@yunshuipiao 需要本地state的意思意思应该是如果这个组件也需要state去缓存一些数据,那个这个组件就不适合无状态组件的写法,无状态组件指的是那些只需要通过props传入数据然后简单展示的组件

@ducaoya
Copy link

ducaoya commented Jul 30, 2021

Hook出现后,就可以在无状态组件中使用state了,并且可以使用相应的Hook达到生命周期函数的效果

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants