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

请教一个 React 问题

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

    我有一个 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
    div class="sep3"> 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     Solana     2644 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 08:50 PVG 16:50 LAX 00:50 JFK 03:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86