简体   繁体   English

你怎么能重构并使反应变得不那么笨重和可读性?

[英]How can you refactor and make react less bulky and more readable?

Is there any way to make React code such as the component I've posted below less clunky and more readable? 是否有任何方法可以使React代码(例如我在下面发布的组件)更少笨重且更具可读性? Should I break out my table data into components somehow? 我应该以某种方式将我的表数据分解成组件吗? Just wondering, as I'm new to this, and think that this doesn't look great, but I'm not sure. 只是想知道,因为我是新手,并认为这看起来不太好,但我不确定。 Thanks so much for any input. 非常感谢任何输入。

class Profile extends Component {

    componentWillMount() {
        const { id } = this.props.match.params;
        this.props.getStarshipsData(id);
    }

    successfulLoad(itemStatus) {
        return (itemStatus === 'SUCCESS');
    }

    findPersonById(people, idNumber) {
        return people.filter(person => {
            return person.url === `http://swapi.co/api/people/${idNumber}/`;
        });
    }

    renderLoadingMessage() {
        if (!this.successfulLoad(this.props.starships.status)) {
            return <p id="loading-text">{ 'Loading' }</p>;
        }
        return null;
    }

    renderTable() {
        if (this.successfulLoad(this.props.starships.status)) {
            return (
                <table id="starship-data-table">
                    <tbody>
                        <tr>
                            <th className="starship-data-header">Name</th>
                            <th className="starship-data-header">Model</th>
                            <th className="starship-data-header">Length</th>
                            <th className="starship-data-header">Cost in Credits</th>
                            <th className="starship-data-header">Crew</th>
                            <th className="starship-data-header">Hyperdrive Rating</th>
                        </tr>
                        { this.renderStarships() }
                    </tbody>
                </table>
            );
        }
        return null;
    }

    renderStarships() {
        if (this.successfulLoad(this.props.starships.status)) {
            const { starships } = this.props.starships.data;
                return (
                    starships.map((starship, index) => {
                        return (
                            <tr key={index} className="starship-container">
                                <td className="starship-data">{starship.name}</td>
                                <td className="starship-data">{starship.model}</td>
                                <td className="starship-data">{starship.length}</td>
                                <td className="starship-data">{starship.cost_in_credits}</td>
                                <td className="starship-data">{starship.crew}</td>
                                <td className="starship-data">{starship.hyperdrive_rating}</td>
                            </tr>
                        );
                    })
                );
        }
        return;
    }

    render() {
        const { id } = this.props.match.params;
        const { people } = this.props.people.data;
        const person = this.findPersonById(people, id)[0];

        return (
            <div id="profile-page">
                <div id="profile-attributes-container">
                    <div id="profile-picture-name">
                        <p className="profile-attribute">{ person.name } </p>
                        <img id="profile-picture" role="presentation" src={profilePicture} />
                    </div>
                    <div id="profile-row-1">
                        <p className="profile-attribute"> Hgt: { person.height } </p>
                        <p className="profile-attribute"> Mass: { person.mass } </p>
                        <p className="profile-attribute"> Hair: { person.hair_color } </p>
                    </div>
                    <div id="profile-row-2">
                        <p className="profile-attribute"> Eyes: { person.eye_color } </p>
                        <p className="profile-attribute"> Born: { person.birth_year } </p>
                        <p className="profile-attribute"> Gen: { person.gender } </p>
                    </div>
                </div>
                <div id="starships-info">
                    <img id="starships-title" role="presentation" src={spaceship} />
                    <div id="starships-table">
                    { this.renderTable() }
                    { this.renderLoadingMessage() }
                    </div>
                </div>
            </div>
        );
    }
}

const mapStateToProps = state => {
    const { starships, people } = state;
    return { starships, people };
};

const mapDispatchToProps = dispatch => {
    return {
        getStarshipsData: starships => {
            dispatch(starshipsActions.getStarshipsData(starships));
        },
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(Profile);

You can use stateless functional components. 您可以使用无状态功能组件。 These are normal functions that React will render as components. 这些是React将作为组件呈现的常规函数​​。 This is great for making code smaller and more readable! 这非常适合使代码更小,更易读!

The props are passed in as an object, so you can use object destructuring to access specific properties: 道具作为对象传入,因此您可以使用对象解构来访问特定属性:

// returns a loading message
const LoadingMessage = ({message}) =>
  <p id="loading-text">{ message }</p>


// returns a <tbody> containing a row for each starship
const StarshipTableRows = ({starships}) =>
  <tbody>
    starships.map((starship, index) => 
      <tr key={index} className="starship-container">
        ['name', 'model', 'length', 'cost_in_credits', 'crew', 'hyperdrive_rating']
          .map(key => <td className="starship-data">{starship[key]}</td>)
      </tr>);
  </tbody>


// returns a <thead> containing headers for the table
const StarshipTableHeaders = () =>
  <thead>
    <tr>
      ['Name', 'Model', 'Length', 'Cost in Credits', 'Crew', 'Hyperdrive Rating']
        .map(key => <th className="starship-data-header">{key}</td>)
    </tr>
  </thead>


// returns a <table> containing starships
const StarshipTable = ({starships}) =>
  <table id="starship-data-table">
   <StarshipTableHeaders />
   <StarshipTableRows starships={starships.data} />
  </table>


// returns a profile page
const ProfilePage = ({person, profilePicture, spaceship, starships, successfulLoad}) => 
  <div id="profile-page">
    <div id="profile-attributes-container">
      <div id="profile-picture-name">
        <p className="profile-attribute">{ person.name } </p>
        <img id="profile-picture" role="presentation" src={profilePicture} />
      </div>
      <div id="profile-row-1">
        <p className="profile-attribute"> Hgt: { person.height } </p>
        <p className="profile-attribute"> Mass: { person.mass } </p>
        <p className="profile-attribute"> Hair: { person.hair_color } </p>
      </div>
      <div id="profile-row-2">
        <p className="profile-attribute"> Eyes: { person.eye_color } </p>
        <p className="profile-attribute"> Born: { person.birth_year } </p>
        <p className="profile-attribute"> Gen: { person.gender } </p>
      </div>
    </div>
    <div id="starships-info">
      <img id="starships-title" role="presentation" src={spaceship} />
      <div id="starships-table">
        { 
          successfulLoad
          ? <StarshipTable starships={starships} />
          : <LoadingMessage message="loading" />
        }
      </div>
    </div>
  </div>

const mapStateToProps = state => {
  const { starships, people } = state;
  return { starships, people };
};

const mapDispatchToProps = dispatch => {
  return {
      getStarshipsData: starships => {
          dispatch(starshipsActions.getStarshipsData(starships));
      },
  };
};

class Profile extends Component {

  componentWillMount() {
    const { id } = this.props.match.params;
    this.props.getStarshipsData(id);
  }

  findPersonById(people, idNumber) {
    return people.filter(person => 
      person.url === `http://swapi.co/api/people/${idNumber}/`;
    );
  }

  render() {
    const { id } = this.props.match.params;
    const { people } = this.props.people.data;
    const person = this.findPersonById(people, id)[0];
    const starships = this.props.starships;
    const successfulLoad = starships.status === 'SUCCESS';

    return <ProfilePage 
      person={person} 
      successfulLoad={successfulLoad} 
      starships={starships} 
      spaceship={null} 
      profilePicture={null}/>;
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Profile);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM