首页 文章

已解决 - 商店更改不会在组件中重新呈现计算功能

提问于
浏览
0

EDIT

昨天我正在解决这个问题,我想出来了 . 不幸的是,这不是我提出的代码中的问题= /

问题是我的PHPStorm自动添加了来自' mobx/lib/mobx ' (and should be just ' mobx '的mobx元素的导入 . 这导致打开另一个mobx实例 .


我遇到React / MobX从Component看到商店变化的问题 . 这是我得到的:

  • Store: 用于管理商店的类(我的表的列的可见性),得到了@observable Map .

  • Listing: 为当前表创建存储的组件,绘制它的控制面板和表本身(不包括在示例中) .

  • Buttons: 用于列出所有列名称和onClick的控制器组件,用于更改其可见性 . 还有状态显示/隐藏所有列表 .

每当我点击列表中的任何按钮元素时,它都会更改状态(正在更改存储),但按钮组件不会重新渲染,因此我将其值视为旧值 . 手动重新渲染(更改显示按钮状态的两倍)后,列表会正确呈现,直到我再次单击 .

以下是产生问题的代码:

Store:

export default class ColumnStore {
    constructor(columns) {
        this.showed = extendObservable(new Map());
        columns.map(column => {
            this.showed.set(column.id, column.show);
        });
    }

    @action changeShow(showId, showValue) {
        if (this.showed.has(showId)) {
            this.showed.set(showId, showValue);
        }
    }
}

Listing:

@observer
export default class Listing extends Component {
    constructor(props) {
        super(props);
        this.store = new ColumnStore(this.getColumns);
    }

    @computed get getColumns() {
        return [
            {id: 'first', show: true},
            {id: 'second', show: true},
            {id: 'third', show: true}
        ]
    }

    render() {
        return (
           <Buttons store={this.store}/>
        );
    }
}

Buttons:

@observer
export default class Buttons extends Component {
    static propTypes = {
        store: PropTypes.instanceOf(ColumnStore).isRequired
    };

    constructor(props) {
        super(props);
        this.state = {
            columnListOpen: false
        }
    }

    toggleColumnList = () => {
        this.setState({
            columnListOpen: !this.state.columnListOpen
        })
    }

    @computed get renderButton() {
        return <button className="btn" onClick={this.toggleColumnList}>Show/hide</button>;
    }

    @computed get renderListData() {
        let columns = []
        this.props.store.showed.forEach((value, id) => {
            columns.push(<span key={id} className={`column` + (value ? ' visible' : '')} onClick={() => {
                this.props.store.changeShow(id, !value)
            }}>
                {id} ({value ? 'T' : 'F'})
            </span>)
        });
        return columns;
    }

    @computed get renderList() {
        return this.state.columnListOpen ? this.renderListData : '';
    }

    render() {
        return (
            <div>
                {this.renderButton}
                {this.renderList}
            </div>
        );
    }
}

1 回答

  • 0

    您需要更改商店的构造函数以使用 observable 而不是 extendObservable 来创建 showed

    class ColumnStore {
      constructor(columns) {
        this.showed = observable(new Map());
        columns.map(column => {
          this.showed.set(column.id, column.show);
        });
      }
    

    更简洁的方法是使用 observable 作为装饰器:

    class ColumnStore {
      @observable showed = new Map();
    
      constructor(columns) {
        columns.map(column => {
          this.showed.set(column.id, column.show);
        });
      }
    

相关问题