【问题标题】:How to use dynamically created classes in react components如何在反应组件中使用动态创建的类
【发布时间】:2018-05-04 22:18:55
【问题描述】:

我有一个这种形式的类:

 export default class FixedMem {
    constructor(totalMem){
      this._totalMem = totalMem
        }

    get totalMem(){
     return this._totalMem
    }
    addMem(mem){
      this._totalMem += mem
    }
   }

我像这样将它导入到我的反应组件中:

    import Fixed from '../somewhere'

如果我想根据来自文本框的输入创建具有不同参数的新类并显示其值。我如何从渲染方法内部调用它的方法?这多少说明了我的问题

class fixedBlock extends Component {
     constructor(){
       super()
       this.state = {
         "textInput":"",
         "totalMem":0,
         "fixed":null
         }
      }

     handleInputChanged(e){
      this.setState({
       "textInput":e.target.value
       }) 
      }

     handleButtonPressed(){
        this.setState({"fixed":new Fixed(parseInt(this.state.textInput))})
       }

     incrementButtonPressed(){
         this.state.fixed.addMem(2) 
     }

 render(){
    return(
   <div>
     <input type="button" onClick={this.handleInputChanged} value=
     {this.state.textInput}>
     <button onClick={this.handleButtonPressed}>create</button>
     <button onClick={this.incrementButtonPressed}> increment </button>
       <p>{this.state.fixed.totalMem}</p>
      </div>
     )

   }

  }

这不起作用,我必须解决这个问题的另一种方法是使用闭包,所以在我的反应组件中:

class fixedBlock extends Component{
  constructor(){//stuff here}

 FixedMem () {
   var FixedObj = null
   return {
       initFixed: function (totalMem) {
        FixedObj = new Fixed(totalMem, divisions)
  },
  totalMem: function () {
    return FixedObj.totalMem
  },
  increment: function(){
    FixedObj.addMem(2)
    }


   render(){//stuff here}

    }

我如何在渲染方法中使用它?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    第一次尝试的问题是你在不让 React 知道的情况下改变组件的状态。您需要使用setState() 或forceUpdate()。在让 React 知道的同时让 FixedMem 管理您的状态的一种方法可能是:

    class FixedBlock extends Component {
      constructor(props) {
        super(props);
        this.state = {
          textInput: '',
          totalMem: 0
        };
        this.fixedMem = new FixedMem(0);
        this.sync = this.sync.bind(this);
      }
    
      sync() {
        const totalMem = this.fixedMem.totalMem;
        this.setState({ totalMem });
      }
    
      handleInputChanged(evt) {
        this.setState({ textInput: evt.target.value });
      }
    
      handleButtonPressed() {
        this.fixedMem = new FixedMem(parseInt(this.state.textInput));
        this.sync();
      }
    
      incrementButtonPressed() {
        this.fixedMem.addMem(2);
        this.sync();
      }
    
      render() {
        return (
          <div>
            <input type="text" onChange={this.handleInputChanged.bind(this)} />
            <button onClick={this.handleButtonPressed.bind(this)}>create</button>
            <button onClick={this.incrementButtonPressed.bind(this)}>increment</button>
            <p>{this.state.totalMem}</p>
          </div>
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      您的代码示例存在几个问题。缺少结束标记和缺少方法的重新绑定。

      这是一个在 React 组件中动态使用类实例的示例。但是我不建议使用这种方法。这主要是作为概念证明。

      class MyValue {
        constructor(val) {
          this._val = parseInt(val, 10) || 0;
        }
        get total() {
          return this._val;
        }
        set total(val) {
          this.val = val;
        }
        add(val) {
          this._val += val;
        }
        subtract(val) {
          this._val -= val;
        }
      }
      

      这是 React 组件

      class Block extends React.Component {
        constructor() {
          super();
          this.state = {
            textInput: "",
            myValue: new MyValue()
          };
        }
      
        handleInputChanged(e) {
          this.setState({
            textInput: e.target.value
          });
        }
      
        handleButtonPressed() {
          this.setState({ myValue: new MyValue(this.state.textInput) });
        }
      
        incrementButtonPressed() {
          this.state.myValue.add(2);
          this.forceUpdate(); /* React does not know the state has updated, force update */
        }
      
        render() {
          return (
            <div>
              <input type="number" step="1" onChange={this.handleInputChanged.bind(this)} />
              <button onClick={this.handleButtonPressed.bind(this)}>create</button>
              <button onClick={this.incrementButtonPressed.bind(this)}>increment</button>
              <p>{this.state.myValue.total}</p>
            </div>
          );
        }
      }
      

      作为替代方法。您可以使用将逻辑与表示分开的模式。这是一个使用函数作为子函数的示例。计算器处理计算,Presentation 使用计算器并呈现 GUI。

      class Calculator extends React.Component {
        constructor() {
          super();
          this.state = {value: 0};
        }
        add(value){
          this.setState(prevState => ({value: prevState.value + value}));    
        }
        subtract(value){
          this.setState(prevState => ({value: prevState.value - value}));
        }
        set(){
          this.setState(prevState => ({value: parseInt(prevState.input, 10) || 0}));
        }
        input(value){
          this.setState({input: value});
        }
        render() {    
          return this.props.children(
            {
              value: this.state.value, 
              add: this.add.bind(this),
              subtract: this.subtract.bind(this),
              set: this.set.bind(this),
              input: this.input.bind(this),
            });
        }
      }
      
      const Presentation = props => (
          <Calculator>
            { ({value,add,subtract,set,input}) => (
              <div>
                <button onClick={() => add(2)}>add 2</button>
                <button onClick={() => subtract(3)}>subtract 3</button>
                <input type="number" step="1" onChange={e => input(e.target.value)} />
                <button onClick={set}>set</button>
                <p>{value}</p>
              </div>)
            }
          </Calculator>);
      

      【讨论】:

        猜你喜欢
        • 2019-12-06
        • 2022-11-01
        • 1970-01-01
        • 2021-04-14
        • 2014-10-02
        • 2021-06-11
        • 1970-01-01
        • 2018-10-11
        • 2017-06-28
        相关资源
        最近更新 更多