Skip to content

Instantly share code, notes, and snippets.

@BigAB
Last active September 29, 2016 08:20
Show Gist options
  • Save BigAB/b94f58a634c64453e08ab61c26f764c2 to your computer and use it in GitHub Desktop.
Save BigAB/b94f58a634c64453e08ab61c26f764c2 to your computer and use it in GitHub Desktop.
CanReact problem: props always win

This just tries to demostrate the fact that because attr1 is supplied by props, even though the viewModels property keeps getting set, it just keeps going back to the props value because of the current implementation. To run the demo:

  • clone this repo (a gist is a repo)
  • run npm install (or npm i if you're nasty)
  • run npm start and checkout http://localhost:3000/
<!DOCTYPE html>
<html>
<head>
<title>The problem with keys Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app"></div>
<br/><br/>
<small><i>Psst... Look in the console</i></small>
<script src="node_modules/steal/steal.js" main="@empty">
import React from 'react';
import ReactDOM from 'react-dom';
import { connect } from '@bigab/can-react/';
import Map from 'can-define/map/';
const Child1 = createChildComponent('Child1');
const Child2 = createChildComponent('Child2');
const Example = createExampleComponent(Child1, Child2);
const App = props => {
return <Example attr1={ 'Initial value' }/>
}
ReactDOM.render(<App />,
document.getElementById('app')
);
function createExampleComponent(Child1, Child2) {
const ViewModel = Map.extend({
attr1: {
value: 'one'
},
attr2: {
value: '2 on'
},
toggleVal() {
this.attr1 = this.attr1 === 'one' ? 'not one' : 'one';
this.attr2 = this.attr2 === '2 on' ? '2 off' : '2 on';
},
init() {
window.vm = this
}
});
const Example = ({ attr1, attr2, toggleVal }) => {
return (
<div>
<h1>Child Attr Check</h1>
<pre>
<p>attr1: {attr1}</p>
<p>attr2: {attr2}</p>
</pre>
<ul>
<li><Child1 val={ attr1 } /></li>
<li><Child2 val={ attr2 }/></li>
</ul>
<button onClick={ toggleVal }>Toggle Val</button>
</div>
)
}
return connect(ViewModel, Example);
}
function createChildComponent(name = '') {
const names = name ? name + ' ' : '';
let initCount = 0;
const ViewModel = Map.extend({
val: {
value: null
},
init() {
this.on('val', ()=>{ console.log(`${names}Val changed`) })
initCount++;
console.log(`${names}Init called ${initCount} time${initCount!==1?'s':''}`)
},
handleClick() {
this.val = null;
}
});
const Component = ({ val, handleClick }) => {
return (
<div><span>{ val }</span><button onClick={handleClick}>x</button></div>
)
}
return connect(ViewModel, Component);
}
</script>
</body>
</html>
{
"name": "@bigab/bitovi-can-react-problem",
"version": "0.0.1",
"description": "",
"main": "index.html",
"scripts": {
"start": "serve"
},
"keywords": [],
"author": "BigAB <bigab@live.ca> (bigab.net)",
"license": "MIT",
"dependencies": {
"@bigab/can-react": "0.0.3",
"can": "^3.0.0-pre.11",
"can-define": "^0.7.24",
"done-serve": "^0.2.5",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"serve": "^1.4.0"
},
"devDependencies": {
"steal": "^1.0.0-rc.3"
},
"system": {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment