如何使变量可用于组件中的每个方法?

Posted

技术标签:

【中文标题】如何使变量可用于组件中的每个方法?【英文标题】:How to make variables available to every method in a component? 【发布时间】:2019-02-14 10:55:08 【问题描述】:

假设我将我的商店状态映射到道具,如下所示:

const mapStateToProps = state => 
    return 
        somelist: state.somelist
    ;
;

我需要在我的渲染中创建变量,例如:

render() 
  const  somelist  = this.props;
  const somenestedlist = somelist.list;

但是,在我的渲染方法中,我还调用了另一个需要这些相同变量的方法。所以我可以:

(1) 从 render 方法中传递它,例如:

render() 
  const  somelist  = this.props;
  const somenestedlist = somelist.list;

  <div onClick=()=>this.someothermethod(somenestedlist)

(2) 在非 DRY 的someothermethod() 中重新声明它们。

(3) 创建一个返回所需值的函数,并在任何需要的地方调用它,如下所示:

getList() 
  const  somelist  = this.props;
  const somenestedlist = somelist.list;

  return somenestedlist;

或者有没有比这些例子更好的方法?

【问题讨论】:

this.props 已经在组件中的任何位置可用,这基本上回答了您的问题。除此之外,一切都只是意见 【参考方案1】:

你可以在 mapStateToProps 中将 somelist 和 somelist.list 构造成一个对象并返回该对象。类似下面的东西

const mapStateToProps = state => 
    const obj = ;
    obj.somelist = state.somelist;
    obj.someNestedList = state.somelist.list;
    return 
        list: obj
    ;
;

在渲染中,您可以从列表道具对象中获取 somelist 和 someNestedList ,而无需分配给局部变量。类似下面的东西

 someothermethod = list => 
      console.log(list.someList);
      console.log("someNestedList", list.someNestedList);
 
 render() 
      const  list  = this.props;
      console.log("somelist", list.somelist);
      console.log("someNestedList", list.someNestedList);
      return(
         <div onClick=()=>this.someothermethod(list)></div>
      )
    

【讨论】:

【参考方案2】:

如果您不想在使用的每个函数中重新声明变量,那么...我认为您唯一的选择是直接使用 props 中的值...

然后,这样做:

yourMethod()
    //Do somethign with data directly, no need to declare a const again
    this.anotherMethod(this.props.somelist.list);

代替:

const  somelist  = this.props;
const somenestedlist = somelist.list;

我的意思是,这些值已经可用于所有方法,只需使用它们...const somelist = this.props; 仅用作帮助,不要在整个方法中写入this.props.somelist

【讨论】:

【参考方案3】:

如果您不需要更改列表,则可以从任何类的方法中访问 this.props.someList

但是,如果您想在组件内从该列表中添加/删除项目而不更改someList,那么最简单的解决方案是在class constructor 中从someList 源声明nestedList 变量(下面的示例,其中state = ... 是同一事物的语法糖),然后利用 React 状态来更改这个新列表。

现在,您可以丢弃新列表或调用 Redux 操作创建者来保存和更新道具列表(因此,只要初始列表源保持不变,您也可以重置两个列表)。

工作示例:https://codesandbox.io/s/6w5r5o32qk

import React,  Component, Fragment  from "react";
import  connect  from "react-redux";
import  resetList, saveList  from "./listActions";

const newData = [
  
    _id: "5b9c3b351e5f7d9b827df4ce",
    index: 0,
    guid: "048e6f79-c33c-42fc-83e3-05f5b467240d",
    isActive: false,
    balance: "$1,663.79",
    picture: "http://placehold.it/32x32",
    age: 23,
    name: "Tonya Drake"
  ,
  
    _id: "5b9c3b350e7b14d4c94043f2",
    index: 1,
    guid: "1e3daeeb-36fd-4e52-a30e-5dbaedec8438",
    isActive: true,
    balance: "$2,263.69",
    picture: "http://placehold.it/32x32",
    age: 40,
    name: "Patricia Phelps"
  
];

class Example extends Component 
  state = 
    addButtonClicked: false,
    saveButtonClicked: false,
    nestedList: this.props.someList
  ;

  componentDidUpdate = prevProps => 
    if (prevProps.someList !== this.props.someList) 
      this.setState(
        nestedList: this.props.someList
      );
    
  ;

  addData = () => 
    this.setState(prevState => (
      addButtonClicked: true,
      nestedList: [...this.state.nestedList, newData]
    ));
  ;

  resetData = () => 
    this.setState(prevState => 
      this.props.resetList();
      return 
        addButtonClicked: false,
        saveButtonClicked: false,
        nestedList: this.props.someList
      ;
    );
  ;

  saveNewList = () =>
    this.setState(prevState => 
      this.props.saveList(this.state.nestedList);
      return  saveButtonClicked: true ;
    );

  render = () => (
    <div style= textAlign: "center" >
      <h1>Utilizing React State</h1>
      <button
        className="uk-button uk-button-primary uk-button-large"
        type="button"
        onClick=this.addData
        disabled=this.state.addButtonClicked || this.state.saveButtonClicked
        style= marginRight: 20 
      >
        Add Data
      </button>
      <button
        type="button"
        className="uk-button uk-button-danger uk-button-large"
        onClick=this.resetData
        disabled=!this.state.addButtonClicked && !this.state.saveButtonClicked
        style= marginRight: 20 
      >
        Reset List
      </button>
      <button
        type="button"
        className="uk-button uk-button-secondary uk-button-large"
        onClick=this.saveNewList
        disabled=
          (this.state.addButtonClicked && this.state.saveButtonClicked) ||
          (!this.state.addButtonClicked && !this.state.saveButtonClicked)
        
      >
        Save List
      </button>
      <pre style= height: 600, overflowY: "auto", textAlign: "left" >
        State List&nbsp;
        <code>JSON.stringify(this.state.nestedList, null, "\t")</code>
        <br />
        <br />
        Props List&nbsp;
        <code>JSON.stringify(this.props.someList, null, "\t")</code>
      </pre>
    </div>
  );


export default connect(
  state => ( someList: state.list ),
   resetList, saveList 
)(Example);

【讨论】:

【参考方案4】:

您可以在 mapStateToProps 中转换 somenestedlist:

const mapStateToProps = state => 
    return 
        somelist: state.somelist,
        somenestedlist: state.somelist.list
    ;
;

在任何地方,你都可以使用 this.props.somenestedlist

【讨论】:

【参考方案5】:

如果您想在特定组件中使用变量,您可以使用以下选项:

1.使用道具

2.使用状态

3.在你的组件中声明一个变量

4.为组件使用 store 并在 store 中声明变量并将 store 传递给您的组件

5.....

如果您想在多个组件中使用特定变量,您可以使用以下选项:

1.声明父组件或基础组件并在其中声明变量并通过props将其传递给子组件

2.您可以为多个组件使用特定的存储并在其中声明变量

3....

但要小心在复杂情况下使用变量,错误使用很容易降低项目性能

你也可以使用 observable 属性来改变和命令自动重新渲染

【讨论】:

以上是关于如何使变量可用于组件中的每个方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 configureWebpack 使自定义变量可用于组件?

如何使组件道具可用于其开槽元素?

如何对服务中的 BehaviorSubject 变量进行单元测试,它是组件中的可观察对象

访问每个组件中的颜色变量

Java 使组件相互通信

useState hook如何知道react中的调用上下文