非常感谢任何帮助:
Mobx似乎在子组件和父组件之间失去状态。
我在下面制作了一个小提琴演示。包含注释和输出以便清晰。
(React,Mobx和Mobx-React的当前版本)
感谢。
JSFIDDLE DEMO HERE
https://jsfiddle.net/ymp1g6qk/3/
在此发现的展示
CONSOLE OUTPUT HERE
此处的示例代码:
const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM
const {autorun} = mobx
class MyItem {
id = 0;
@observable name = "";
@observable selected = false;
constructor(id, name, selected) {
this.id = id;
this.name = name;
this.selected = selected;}
}
/* ESTIMATE STORE */
// @observable <---- Observable not allowed. Generates "Not a Constructor Error"
class MyStore extends Component {
@observable items = [];
constructor() {
super();
this.items.push(new MyItem(1, 'copper' ));
this.items.push(new MyItem(10, 'Silver' ));
this.items.push(new MyItem(20, 'Gold' ));
this.items.push(new MyItem(30, 'Platinum'));
this.items.push(new MyItem(40, 'Sapphire'));
this.items.push(new MyItem(50, 'Diamond' ));
console.log("finished with MyStore:", this.items, " with count: ", this.items.length, " items.");
}
}
let MyItems = new MyStore();
@observer
class MyCard extends Component {
constructor(props){
super(props)
}
_toggle(e){
console.log("... At (Child) Component");
console.log("click event generates id:", e, "...and calls parent component function that was passed as a prop. (it succeeds)");
this.props.onToggleSelection(e);
}
render() {
return (
<li onClick={this._toggle.bind(this, this.props.id )} className={(this.props.selected ? " selected" : "")}>
<p>{this.props.name}</p>
</li>
)
}
}
@observer
class Test extends Component {
/* selections */
item = 0;
@observable selectedMyItems = [];
@computed get itemsSelected() {
return this.selectedMyItems.length;
}
constructor( props ){
super( props );
}
componentWillReceiveProps(nextProps, nextContext) {
console.log(" ...At panel will recieve props and selectedMyItems:", this.selectedMyItems.length);
}
componentDidMount() {
console.log(" ...At DidMount, and selectedMyItems:", this.selectedMyItems.length);
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log(" ...At ShouldUpdate, and selectedMyItems:", this.selectedMyItems.length);
return null;
}
componentWillUpdate(nextProps, nextState, nextContext) {
console.log(" ...At WillUpdate and selectedMyItems:", this.selectedMyItems.length);
}
componentDidUpdate(prevProps, prevState, prevContext) {
console.log(" ...At DidUpdate and selectedMyItems:", this.selectedMyItems.length);
}
componentWillUnmount () {
console.log(" ...At DidUnmount and selectedMyItems:", this.selectedMyItems.length);
}
toggleSelection(id){
var itemindex = -1;
console.log("...At (parent) _toggle selection:", id );
/* find the clicked item */
itemindex = MyItems.items.findIndex((MyItem => MyItem.id == id));
console.log("...the id of the item is :", id);
console.log("...the item's index is:", itemindex);
console.log("...the record for that id is:", MyItems.items[itemindex]);
console.log("...selected items array consists of:", this.selectedMyItems); // <<< Warning: "Undefined"
console.log("...See??? The array is undefined:", this.selectedMyItems);
/* toggle selected */
MyItems.items[itemindex].selected = !MyItems.items[itemindex].selected; // <<< Succeeds.
/* add or remove the selected item */
if ( MyItems.items[itemindex].selected ) {
/* add the item to the list of selected items */
console.log("...See??? The next line's push to the array fails: undefined:", this.selectedMyItems);
this.selectedMyItems.push(id); // <<< ERROR: "Cannot read property 'push' of undefined"
} else {
/* remove the item from the list of selected items */
this.selectedMyItems.splice(this.selectedMyItems.indexOf(id), 1); // <<< ERROR: "Cannot read property 'splice' of undefined"
}
// this.props.uistore.doCommand({cmd: "TOGGLE_PANEL_SELECTION", pld:{ panelname:"estimate", id: choice }});
}
render() {
var i = 1;
return (
<div id="my-panel">
Open the Console.<br/>
Click on an item in the list to select or unselect it.<br/>
Note that selectedMyItems is out of scope (unassigned). Why?
<ul className="">
{MyItems.items.map(MyItem => {
return (
<MyCard key={i++} id={MyItem.id} name={MyItem.name} selected={MyItem.selected} tags={MyItem.tags} onToggleSelection={this.toggleSelection}/>
)
})}
</ul>
<ul className=""></ul>
</div>
);
}
};
ReactDOM.render(<Test/>, app);
答案 0 :(得分:0)
toggleSelection(id)
中的方法class Test
未绑定。
你应该在类Test构造函数(首选)中绑定它:
class Test extends Component {
constructor() {
this.toggleSelection = this.toggleSelection.bind(this);
}
...
}
或“就地”绑定它:
<MyCard ... onToggleSelection={this.toggleSelection.bind(this)}/>
检查更新的jsFiddle版本:https://jsfiddle.net/ymp1g6qk/6/