V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
AAASUKA
V2EX  ›  问与答

请教一个 React 问题

  •  
  •   AAASUKA · 2020-07-02 14:47:40 +08:00 · 1780 次点击
    这是一个创建于 1635 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个 class Chart 组件用来绘制图表
    现在有一个 data[]数组存储若干组数据
    我做了一个下拉框,希望能在选择不同的数据来绘制图表
    我现在的情况是默认使用 data[0]绘制数据,但是下拉框更新后,图表不会更新 这种希望图表能随着选择重新渲染、绘制的情况,有没有什么解决方案 这个图表初始为空,点击一次下拉框后出现,再选择下拉框就不会变了

    class Main extends Component {
      constructor(props) {
           super(props);
           this.state = {
              value: 0,
              chart: this.draw(0),
           };
        this.handleChange = this.handleChange.bind(this);
        this.draw = this.draw.bind(this);
      }
    
      handleChange(event) {
        this.setState({
          value: event.target.value,
          chart: this.draw(event.target.value),
        });
      }
    
      draw(index) {
        return (
        <Chart data={this.props.data[index]}></Chart>
         );
      };
    
      render() {
        var options = <></>
        for (let i = 0; i < this.props.childrenNumber; i++) {
              options = <>{options}<option value={i}>{i+1}</option></>
        }
        return (
          <div>
          <select value={this.state.value} onChange={this.handleChange}>
           {options}</select>
           {this.state.chart}
          </div>
        )
      }
    }
    
    第 1 条附言  ·  2020-07-02 15:41:28 +08:00
    class Main extends Component {
      constructor(props) {
        super(props);
        this.state = {
          value: 0,
        };
        this.handleChange = this.handleChange.bind(this);
      }
      handleChange(event) {
        this.setState({
          value: event.target.value,
        });
      }
      render() {
        var options = <></>
        for (let i = 0; i < this.props.data.length; i++) {
          options = <>{options}<option value={i}>{i+1}</option></>
        }
        return (
          <div>
             <select 
                value={this.state.value} 
                onChange={this.handleChange}>
                    {options}
             </select>
             <Chart 
                data={this.props.data[this.state.value}>
             </Chart>  
        </div>
        );
      }
    }
    

    改成这样也没什么效果,图表不会改变

    17 条回复    2020-07-03 10:02:54 +08:00
    mm163
        1
    mm163  
       2020-07-02 14:56:45 +08:00
    下拉框更新后,把 data[x] 用 props 传给 Chart 组件呀。
    rockjike
        2
    rockjike  
       2020-07-02 15:07:58 +08:00
    为什么把组件放 state 里, 不是放图表数据就好了
    withzhaoyu
        3
    withzhaoyu  
       2020-07-02 15:13:04 +08:00   ❤️ 1
    写法有点奇怪,简单的解决方式是你把 <Chart />上加个 key={index}试试。。。
    AAASUKA
        4
    AAASUKA  
    OP
       2020-07-02 15:13:23 +08:00
    @rockjike 放在图标数据里也不会改变
    rockjike
        5
    rockjike  
       2020-07-02 15:15:38 +08:00   ❤️ 1
    ```
    class Main extends Component {
    constructor(props) {
    super(props);
    const { data = [] } = props
    this.state = {
    current: 0,
    dataList: data,
    };
    this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
    this.setState({
    current: event.target.value
    });
    }


    render() {
    const { dataList, current} = this.state
    var options = <></>
    for (let i = 0; i < this.props.childrenNumber; i++) {
    options = <>{options}<option value={i}>{i+1}</option></>
    }
    return (
    <div>
    <select value={this.state.value} onChange={this.handleChange}>
    {options}</select>
    <Chart data={dataList[current]}></Chart>
    </div>
    )
    }
    }
    ```
    rexchen94
        6
    rexchen94  
       2020-07-02 15:17:38 +08:00
    写法很奇怪,不需要单独写一个 draw 来获得 Chart 组件,直接写 render 里就行,也没必要存在 state 里。试试楼上加个 key
    IGJacklove
        7
    IGJacklove  
       2020-07-02 15:21:06 +08:00
    你这写法看不懂... 一般不都是这么写的吗?

    class Main extends Component {
    constructor(props) {
    super(props);
    this.state = {
    value: 0,
    chartIndex: 0,
    };
    this.handleChange = this.handleChange.bind(this);
    this.draw = this.draw.bind(this);
    }

    handleChange(event) {
    this.setState({
    value: event.target.value,
    chartIndex: event.target.value,
    });
    }

    draw(index) {
    return (
    <Chart data={this.props.data[index]}></Chart>
    );
    };

    render() {
    var options = <></>
    for (let i = 0; i < this.props.childrenNumber; i++) {
    options = <>{options}<option value={i}>{i+1}</option></>
    }
    const {chartIndex} = this.state
    return (
    <div>
    <select value={this.state.value} onChange={this.handleChange}>
    {options}</select>
    {this.draw(chartIndex)}
    </div>
    )
    }
    }
    ljpCN
        8
    ljpCN  
       2020-07-02 15:46:53 +08:00 via Android
    5 楼是正常写法,楼主试了 5 楼的代码再看看吧
    ljpCN
        9
    ljpCN  
       2020-07-02 15:48:55 +08:00 via Android   ❤️ 1
    @ljpCN 没看到附言。原来是已经写成 5 楼的写法了。那你应该检查一下你的 chart 组件是不是能做到对 props 动态响应。
    YadongZhang
        10
    YadongZhang  
       2020-07-02 15:50:10 +08:00 via Android
    for 循环什么意思
    AAASUKA
        11
    AAASUKA  
    OP
       2020-07-02 15:55:44 +08:00
    @YadongZhang 就是下拉框的可选择项
    YadongZhang
        12
    YadongZhang  
       2020-07-02 15:59:00 +08:00 via Android
    @AAASUKA 所以 value 和 options 什么关系
    baxtergu
        13
    baxtergu  
       2020-07-02 16:08:25 +08:00   ❤️ 1
    ```javascript
    class Main extends Component {
    constructor(props) {
    super(props);
    this.state = {
    value: 0,
    };
    this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
    this.setState({
    value: event.target.value,
    });
    }

    render() {
    const { data = [] } = this.props;
    return (
    <>
    <select value={this.state.value} onChange={this.handleChange}>
    {data.map((item, idx) => (
    <option value={idx} key={JSON.stringify(item)}>
    {idx + 1}
    </option>
    ))}
    </select>
    <Chart data={data[this.state.value]} />
    </>
    );
    }
    }
    ```

    你的 Chart 应该是只有 componentDidMount 的时候渲染了一次,之后就不渲染了,如果是 echarts 的话要手动在 componentWillReceiveProps 周期里面去判断 props.data 是不是改变了然后手动去用 echarts 的 api 去刷新图表
    AAASUKA
        14
    AAASUKA  
    OP
       2020-07-02 16:48:47 +08:00
    @YadongZhang 选项是 1,2,3,4 对应的值是 0,1,2,3
    YadongZhang
        15
    YadongZhang  
       2020-07-02 17:03:00 +08:00 via Android
    我是 React 新手,没看懂 <select> 里的 value 和 onChange (我成了题主了。。。
    AAASUKA
        16
    AAASUKA  
    OP
       2020-07-02 17:07:34 +08:00
    @YadongZhang hhh 我也是刚学没多久,因为下拉框的选项数目是不一定的,所以我用了一个循环,data 有几组数据,下拉框就有几个选项
    cyy564
        17
    cyy564  
       2020-07-03 10:02:54 +08:00
    你先把 Chart 组件给注释了,单纯渲染出 data 中对应 index 的数据,看看有没有变,如果变了的话就是 Chart 的问题了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5497 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:01 · PVG 15:01 · LAX 23:01 · JFK 02:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.