Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:这是使用道具和状态的好方法吗_Javascript_Reactjs - Fatal编程技术网

Javascript 反应:这是使用道具和状态的好方法吗

Javascript 反应:这是使用道具和状态的好方法吗,javascript,reactjs,Javascript,Reactjs,我终于得到了一个实际有效的响应设置。但我非常想得到一些反馈,看看这是否是一个好的设置和数据流 我作了以下发言: App.js App.js scr/dummy-data.js scr/components/ABEval.js import React,{Component}来自'React'; 从“/XSlider”导入XSlider; 类AB_eval扩展了组件{ 构造函数(道具、上下文){ 超级(道具、背景); log(`${this.props.ID}:Constructed`); } c

我终于得到了一个实际有效的响应设置。但我非常想得到一些反馈,看看这是否是一个好的设置和数据流

我作了以下发言:

App.js App.js scr/dummy-data.js

scr/components/ABEval.js

import React,{Component}来自'React';
从“/XSlider”导入XSlider;
类AB_eval扩展了组件{
构造函数(道具、上下文){
超级(道具、背景);
log(`${this.props.ID}:Constructed`);
}
componentDidMount(){
log(`${this.props.ID}:Mounted`);
}
render(){
log(`${this.props.ID}:rendered`)
const{Data,ID}=this.props;
常数{A,B,AB}=数据;
返回(
ABEval:{ID}
A:{A}B:{B}AB:{AB}

this.props.updateDB(ID,{A:val,B:B,AB:val*B}) /> this.props.updateDB(ID,{B:val,A:A,AB:val*A}) /> ) } } AB_eval.propTypes={ ID:React.PropTypes.string.isRequired, 数据:React.PropTypes.object.isRequired, 更新的b:React.PropTypes.func.isRequired }; 导出默认值;
scr/components/XSlider.js

从“React”导入React;
从“react Range Slider”导入滑块;
导出默认值({title,value,valueHandler})=>{
返回(
{title}
);
}

在您的示例中,无需在
App
组件中执行
updateDB
。您只需在
AB_eval
中执行
updateDB
操作即可。您可以在
AB_eval
构造函数中初始化
A
B
,而不是从
App
组件获取,因为它们是常量。

在您的示例中,不必在
App
组件中执行
updateDB
。您只需在
AB_eval
中执行
updateDB
操作即可。您可以在
AB_eval
构造函数中初始化
A
B
,而不是从
App
组件中获取,因为它们是常量。

根据您提供的信息,很难提出许多重新分解的建议,但数据流看起来不错

最新AB_eval.js中的问题:

const {ID, Data} = this.props;  // block scoped, DOES NOT create class members
                                // referencable by this.ID or this.DATA
                                // outside the scope of its containing block
const
是块范围的,因此在 构造函数将仅在 构造块

这将中断以后对
This.ID
This.Data
的引用(在
updateDB()
method)。对
this.A
this.AB
this.B
render()
方法中的
this.updateDB
也将被破坏。修理 这一点,我建议在你的区块范围内分解道具 呈现和onChange处理程序

正在尝试直接在中设置this.props.Data的值 onChange方法有效地改变了应该被视为 不变的

有几种方法可以确保使用ES6/ES7不会发生突变 表示法,一个使用,另一个使用

解决方案

AB_eval.js:

import React, { Component } from 'react';
import Slider from 'react-rangeslider';

class AB_eval extends Component {
  constructor(props, context){
    super(props, context);

    this.onChangeA = this.onChangeA.bind(this);
    this.onChangeB = this.onChangeB.bind(this);
  }

  onChangeA (value) {
    const {ID, Data, updateDB} = this.props;
    updateDB(ID, {
      ...Data,
      A: value,
      AB: value * Data.B
    });
  }

  onChangeB (value) {
    const {ID, Data, updateDB} = this.props;
    updateDB(ID, {
      ...Data,
      B: value,
      AB: value * Data.B
    });
  }

  render() {
    const {A, B, AB} = this.props.Data;
    return (
      <div>
        <h1>AB_eval: {this.props.ID}</h1>

        <h2>A</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={A}
          onChange={this.onChangeA}
        />

        <h2>B</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={B}
          onChange={this.onChangeB}
          }
        />
      </div>
    )
  }
}

AB_eval.propTypes = {
  ID: React.PropTypes.string.isRequired,
  Data: React.PropTypes.object.isRequired,
  updateDB: React.PropTypes.func.isRequired
};

export default AB_eval;
因此,您还必须编辑我建议的AB_eval.js以包括:
从“/components/AB_eval_Slider”导入AB_eval_滑块

现在的渲染方法是:

render() {
  return (
    const { Data } = this.props;
    <div>
      <h1>AB_eval: {this.ID}</h1>
      <AB_eval_Slider key={'A'} db={Data}, handler={this.onChangeA} />
      <AB_eval_Slider key={'B'} db={Data}, handler={this.onChangeB} />
    </div>
  );
}
render(){
返回(
const{Data}=this.props;
AB_eval:{this.ID}
);
}

根据您提供的信息,很难提出许多重新分解的建议,但数据流看起来还行

最新AB_eval.js中的问题:

const {ID, Data} = this.props;  // block scoped, DOES NOT create class members
                                // referencable by this.ID or this.DATA
                                // outside the scope of its containing block
const
是块范围的,因此在 构造函数将仅在 构造块

这将中断以后对
This.ID
This.Data
的引用(在
updateDB()
method)。对
this.A
this.AB
this.B
render()
方法中的
this.updateDB
也将被破坏。修理 这一点,我建议在你的区块范围内分解道具 呈现和onChange处理程序

正在尝试直接在中设置this.props.Data的值 onChange方法有效地改变了应该被视为 不变的

有几种方法可以确保使用ES6/ES7不会发生突变 表示法,一个使用,另一个使用

解决方案

AB_eval.js:

import React, { Component } from 'react';
import Slider from 'react-rangeslider';

class AB_eval extends Component {
  constructor(props, context){
    super(props, context);

    this.onChangeA = this.onChangeA.bind(this);
    this.onChangeB = this.onChangeB.bind(this);
  }

  onChangeA (value) {
    const {ID, Data, updateDB} = this.props;
    updateDB(ID, {
      ...Data,
      A: value,
      AB: value * Data.B
    });
  }

  onChangeB (value) {
    const {ID, Data, updateDB} = this.props;
    updateDB(ID, {
      ...Data,
      B: value,
      AB: value * Data.B
    });
  }

  render() {
    const {A, B, AB} = this.props.Data;
    return (
      <div>
        <h1>AB_eval: {this.props.ID}</h1>

        <h2>A</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={A}
          onChange={this.onChangeA}
        />

        <h2>B</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={B}
          onChange={this.onChangeB}
          }
        />
      </div>
    )
  }
}

AB_eval.propTypes = {
  ID: React.PropTypes.string.isRequired,
  Data: React.PropTypes.object.isRequired,
  updateDB: React.PropTypes.func.isRequired
};

export default AB_eval;
因此,您还必须编辑我建议的AB_eval.js以包括:
从“/components/AB_eval_Slider”导入AB_eval_滑块

现在的渲染方法是:

render() {
  return (
    const { Data } = this.props;
    <div>
      <h1>AB_eval: {this.ID}</h1>
      <AB_eval_Slider key={'A'} db={Data}, handler={this.onChangeA} />
      <AB_eval_Slider key={'B'} db={Data}, handler={this.onChangeB} />
    </div>
  );
}
render(){
返回(
const{Data}=this.props;
AB_eval:{this.ID}
);
}

老实说,我不明白你的代码是干什么用的,但从代码示例和你的问题来看,我不明白 我能想到的是:

dummyData.js

export default {
  one:  {A: 1,
    B: 2,
    AB: 2
  },
  two: { A: 3,
    B: 4,
    AB: 12
  }
};
import React, { Component } from 'react';
import './App.css';
import dummyData from './dummyData';
import AB_eval from './components/AB_eval';

class App extends Component {
  constructor() {
    super();

    // getInitialState
    this.state = dummyData;

    this.updateDB = (id, value) => this.setState({ id: value });

  }

 render() {
   return (
    <div className="App">
      <ul className="list-of-ABs">
          { Object
            .keys(this.state)
            .map(key =>
              <AB_eval
                key = {key}
                ID = {key}
                Data = {this.state[key]}            
                updateDB={this.updateDB} />
            )
          }
        </ul>
     </div>
    );
  }
}

export default App;
import React, { Component } from 'react';
import Slider from 'react-rangeslider';

class AB_eval extends Component {

  constructor(props, context){
    super(props, context);

    this.updateDB = (type, value) => {
      const { ID, DATA } = this.props
      switch(type) {
        case "A":
          this.props.updateDB(
            ID, 
            { ...DATA, A: value, AB: (value * DATA.B) }
          );
          break;
        case "B":
          this.props.updateDB(
            ID, 
            { ...DATA, B: value, AB: (DATA.A * value) }
          );
          break;
        default:
          this.props.updateDB(
            ID, DATA
          );
          break;
      }
    };

  }

  componentDidMount () {
    this.updateDB();
  }

  render() {
    const {A, B, AB} = this.props.DATA;
    return (
      <div>
        <h1>AB_eval: {AB}</h1>

        <h2>A</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={A}
          onChange={ (value)=> this.updateDB("A", value) }
          }
        />

        <h2>B</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={B}
          onChange={ (value)=> this.updateDB("B", value) }
        />
      </div>
    )
  }
}

AB_eval.propTypes = {
  ID: React.PropTypes.string.isRequired,
  DATA: React.PropTypes.object.isRequired,
  updateDB: React.PropTypes.func.isRequired
};

export default AB_eval;
App.js

export default {
  one:  {A: 1,
    B: 2,
    AB: 2
  },
  two: { A: 3,
    B: 4,
    AB: 12
  }
};
import React, { Component } from 'react';
import './App.css';
import dummyData from './dummyData';
import AB_eval from './components/AB_eval';

class App extends Component {
  constructor() {
    super();

    // getInitialState
    this.state = dummyData;

    this.updateDB = (id, value) => this.setState({ id: value });

  }

 render() {
   return (
    <div className="App">
      <ul className="list-of-ABs">
          { Object
            .keys(this.state)
            .map(key =>
              <AB_eval
                key = {key}
                ID = {key}
                Data = {this.state[key]}            
                updateDB={this.updateDB} />
            )
          }
        </ul>
     </div>
    );
  }
}

export default App;
import React, { Component } from 'react';
import Slider from 'react-rangeslider';

class AB_eval extends Component {

  constructor(props, context){
    super(props, context);

    this.updateDB = (type, value) => {
      const { ID, DATA } = this.props
      switch(type) {
        case "A":
          this.props.updateDB(
            ID, 
            { ...DATA, A: value, AB: (value * DATA.B) }
          );
          break;
        case "B":
          this.props.updateDB(
            ID, 
            { ...DATA, B: value, AB: (DATA.A * value) }
          );
          break;
        default:
          this.props.updateDB(
            ID, DATA
          );
          break;
      }
    };

  }

  componentDidMount () {
    this.updateDB();
  }

  render() {
    const {A, B, AB} = this.props.DATA;
    return (
      <div>
        <h1>AB_eval: {AB}</h1>

        <h2>A</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={A}
          onChange={ (value)=> this.updateDB("A", value) }
          }
        />

        <h2>B</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={B}
          onChange={ (value)=> this.updateDB("B", value) }
        />
      </div>
    )
  }
}

AB_eval.propTypes = {
  ID: React.PropTypes.string.isRequired,
  DATA: React.PropTypes.object.isRequired,
  updateDB: React.PropTypes.func.isRequired
};

export default AB_eval;
我首先想到的是您的
AB_eval
组件,它不需要自己的
状态。因为它的所有状态的内容都可以通过
道具
获得。正如
React
上所述,您应该:

计算出应用程序所需状态的绝对最小表示形式,并按需计算所需的所有其他内容

将状态放在一个位置,通常放在组件层次结构顶部的组件中,这会使您更容易理解应用程序

我认为当您想在
React
中创建应用程序时,在
React的
文档站点上的这一点可以帮助您很多

这是一个关于
const
let
的好教程。但简而言之,,
import React from 'react';

export default ({key, db, handler}) => {
  return (
    <div>
      <h2>{key}</h2>
      <p>A: {db.A} B: {db.B} AB:{db.AB}</p>
      <Slider min={1} max={4} step={1} value={key} onChange={handler} />
    </div>
  );
}
render() {
  return (
    const { Data } = this.props;
    <div>
      <h1>AB_eval: {this.ID}</h1>
      <AB_eval_Slider key={'A'} db={Data}, handler={this.onChangeA} />
      <AB_eval_Slider key={'B'} db={Data}, handler={this.onChangeB} />
    </div>
  );
}
export default {
  one:  {A: 1,
    B: 2,
    AB: 2
  },
  two: { A: 3,
    B: 4,
    AB: 12
  }
};
import React, { Component } from 'react';
import './App.css';
import dummyData from './dummyData';
import AB_eval from './components/AB_eval';

class App extends Component {
  constructor() {
    super();

    // getInitialState
    this.state = dummyData;

    this.updateDB = (id, value) => this.setState({ id: value });

  }

 render() {
   return (
    <div className="App">
      <ul className="list-of-ABs">
          { Object
            .keys(this.state)
            .map(key =>
              <AB_eval
                key = {key}
                ID = {key}
                Data = {this.state[key]}            
                updateDB={this.updateDB} />
            )
          }
        </ul>
     </div>
    );
  }
}

export default App;
import React, { Component } from 'react';
import Slider from 'react-rangeslider';

class AB_eval extends Component {

  constructor(props, context){
    super(props, context);

    this.updateDB = (type, value) => {
      const { ID, DATA } = this.props
      switch(type) {
        case "A":
          this.props.updateDB(
            ID, 
            { ...DATA, A: value, AB: (value * DATA.B) }
          );
          break;
        case "B":
          this.props.updateDB(
            ID, 
            { ...DATA, B: value, AB: (DATA.A * value) }
          );
          break;
        default:
          this.props.updateDB(
            ID, DATA
          );
          break;
      }
    };

  }

  componentDidMount () {
    this.updateDB();
  }

  render() {
    const {A, B, AB} = this.props.DATA;
    return (
      <div>
        <h1>AB_eval: {AB}</h1>

        <h2>A</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={A}
          onChange={ (value)=> this.updateDB("A", value) }
          }
        />

        <h2>B</h2>
        <p>A: {A} B: {B} AB:{AB}</p>
        <Slider min={1} max={4} step={1}
          value={B}
          onChange={ (value)=> this.updateDB("B", value) }
        />
      </div>
    )
  }
}

AB_eval.propTypes = {
  ID: React.PropTypes.string.isRequired,
  DATA: React.PropTypes.object.isRequired,
  updateDB: React.PropTypes.func.isRequired
};

export default AB_eval;