【问题标题】:ESlint : Component should be written as a pure function error when I'm creating a class component using reduxESlint:当我使用 redux 创建类组件时,组件应该写成纯函数错误
【发布时间】:2019-05-03 01:07:28
【问题描述】:

我正在我的 react-native 项目中编写一个 react 类组件。我在我的项目中使用 ESLint 来扩展 airbnb 样式规则。

这个组件有一个表单,它在 Redux 中存储它的表单值。它从 Redux 初始化表单值,并使用导入到文件中的操作创建器(称为 employeeUpdate)更新它们。在这种情况下,我的组件中不需要任何生命周期方法或构造函数。

问题在于 ESLint 抱怨我应该将此组件编写为纯函数。我不能把它写成一个纯函数,因为它消耗来自 Redux 的状态作为道具。这是具体的错误:

[eslint] 组件应该写成纯函数

这是我的代码:

import React, { Component } from 'react';
import { Picker, Text } from 'react-native';
import { connect } from 'react-redux';
import { Card, CardSection, Input, Button } from './common';
import { employeeUpdate } from '../actions';

const styles = {
  pickerTextStyle: {
    fontSize: 18,
    paddingLeft: 20
  }
};

class EmployeeCreate extends Component {
  render() {
    const { name, phone, shift, employeeUpdate } = this.props;

    return (
      <Card>
        <CardSection>
          <Input
            label="Name"
            placeholder="Jane"
            value={name}
            onChangeText={value => employeeUpdate({ prop: 'name', value })}
          />
        </CardSection>
        <CardSection>
          <Input
            label="Phone"
            placeholder="555-555-5555"
            value={phone}
            onChangeText={value => employeeUpdate({ prop: 'phone', value })}
          />
        </CardSection>
        <CardSection style={{ flexDirection: 'column' }}>
          <Text style={styles.pickerTextStyle}>Shift</Text>
          <Picker
            selectedValue={shift}
            onValueChange={value => employeeUpdate({ prop: 'shift', value })}
            style={{ flex: 1 }}
          >
            <Picker.Item label="Monday" value="Monday" />
            <Picker.Item label="Tuesday" value="Tuesday" />
            <Picker.Item label="Wednesday" value="Wednesday" />
            <Picker.Item label="Thursday" value="Thursday" />
            <Picker.Item label="Friday" value="Friday" />
            <Picker.Item label="Saturday" value="Saturday" />
            <Picker.Item label="Sunday" value="Sunday" />
          </Picker>
        </CardSection>
        <CardSection>
          <Button>Create</Button>
        </CardSection>
      </Card>
    );
  }
}

const mapStateToProps = state => {
  const { name, phone, shift } = state.employeeForm;
  return { name, phone, shift };
};

export default connect(
  mapStateToProps,
  { employeeUpdate }
)(EmployeeCreate);

我试了一下并尝试将其编写为纯函数(代码如下),但是当我解构动作创建器时,ESLint 再次抱怨我的动作创建器已被声明(因为它是在顶部导入的文件)

import React from 'react';
import { Picker, Text } from 'react-native';
import { connect } from 'react-redux';
import { Card, CardSection, Input, Button } from './common';
import { employeeUpdate } from '../actions';

const styles = {
  pickerTextStyle: {
    fontSize: 18,
    paddingLeft: 20
  }
};

const EmployeeCreate = ({ name, phone, shift, employeeUpdate }) => (
  <Card>
    <CardSection>
      <Input
        label="Name"
        placeholder="Jane"
        value={name}
        onChangeText={value => employeeUpdate({ prop: 'name', value })}
      />
    </CardSection>
    <CardSection>
      <Input
        label="Phone"
        placeholder="555-555-5555"
        value={phone}
        onChangeText={value => employeeUpdate({ prop: 'phone', value })}
      />
    </CardSection>
    <CardSection style={{ flexDirection: 'column' }}>
      <Text style={styles.pickerTextStyle}>Shift</Text>
      <Picker
        selectedValue={shift}
        onValueChange={value => employeeUpdate({ prop: 'shift', value })}
        style={{ flex: 1 }}
      >
        <Picker.Item label="Monday" value="Monday" />
        <Picker.Item label="Tuesday" value="Tuesday" />
        <Picker.Item label="Wednesday" value="Wednesday" />
        <Picker.Item label="Thursday" value="Thursday" />
        <Picker.Item label="Friday" value="Friday" />
        <Picker.Item label="Saturday" value="Saturday" />
        <Picker.Item label="Sunday" value="Sunday" />
      </Picker>
    </CardSection>
    <CardSection>
      <Button>Create</Button>
    </CardSection>
  </Card>
);

const mapStateToProps = state => {
  const { name, phone, shift } = state.employeeForm;
  return { name, phone, shift };
};

export default connect(
  mapStateToProps,
  { employeeUpdate }
)(EmployeeCreate);

有没有办法解决这个问题?我可以不把它写成一个 React 类组件,不使用任何生命周期方法,也不从 ESLint 得到任何错误吗?

注意

  1. 我知道我可以禁用该规则,但我希望在项目的其他组件中收到 ESLint 的警告。
  2. 也许可以使用其他别名导入动作创建器,但我仍然认为这不是编写组件的最佳方式。

【问题讨论】:

    标签: reactjs react-native redux eslint eslint-config-airbnb


    【解决方案1】:

    如果您不需要状态或生命周期方法,纯函数是可行的方法。

    我看到了两种修复代码的方法:

    1. 使用不同的文件进行连接。将 jsx 与纯组件分离到一个文件中,并使用另一个文件连接道具和动作创建者,这很酷。
    2. 如果您希望将所有内容都放在同一个文件中,您可以随时将您的道具重命名为:

      const EmployeeCreate = ({ name, phone, shift, employeeUpdate: updateEmployee }) => (

    现在您的employeeUpdate 在组件内被声明为updateEmployee,并且没有重复声明。

    PS:实际上,使用 Hooks,纯函数可能总是可行的方法。

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 2016-06-20
      • 2017-07-14
      • 2020-10-30
      • 2017-09-08
      • 1970-01-01
      • 2017-02-25
      • 2019-03-30
      • 1970-01-01
      相关资源
      最近更新 更多