Last active
August 29, 2015 14:19
-
-
Save zerkalica/a1d2842ee0de9132eff7 to your computer and use it in GitHub Desktop.
Understanding react-transmit and relay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//__tests__/user-list-test.js | |
import React, {addons} from 'react/addons' | |
import UserList from '../user-list' | |
const tu = addons.TestUtils | |
const fakeUsers = [ | |
{ | |
id: 1, | |
name: 'user 1' | |
}, | |
{ | |
id: 2, | |
name: 'user 2' | |
}, | |
{ | |
id: 3, | |
name: 'user 3' | |
}, | |
{ | |
id: 4, | |
name: 'user 4' | |
} | |
] | |
jest.dontMock('../user-list.js') | |
jest.dontMock('../user.js') | |
describe('user-list-test', () => { | |
it('should generate valid user list', () => { | |
const fakeQueryParams = { | |
currentId: 1, | |
error: { | |
message: '' | |
} | |
} | |
const userList = tu.renderIntoDocument( | |
<UserList users={fakeUsers} queryParams={fakeQueryParams}/> | |
) | |
expect(document.querySelector('.user-name-1').textContext).toEqual('user 1'); | |
}) | |
}) | |
/* | |
1. Without dom emulation: how to provide fakeQueryParams and reproduce state of UserList without rendering into document (componentWillMount not called) | |
2. With dom emulation: Mocking fetch in UserList is right way ? | |
3. How to change UserList state without fetching new users. We don't use setState, only setQueryParams ? | |
4. How to do onUserDelete action right way in relay paradigm, without flux actions/stores | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//user-list.js | |
import React, {PropTypes as p} from 'react' | |
import {createContainer} from 'react-transmit' | |
import fetch from 'isomorphic-fetch' | |
class UserList extends React.Component { | |
static propTypes = { | |
users: p.arrayOf(User.propTypes.user), | |
queryParams: p.shapeOf({ | |
currentId: p.number, | |
error: p.shapeOf({ | |
message: p.string | |
}), | |
deleteAction: p.oneOf('progress', null, 'fail') | |
}) | |
} | |
onNextUsers() { | |
this.props.setQueryParams({ | |
currentId: this.props.queryParams.currentId + 2 | |
}) | |
} | |
onUserDelete(id) { | |
this.props.setQueryParams({ | |
deleteAction: 'progress', | |
deleteUserId: id | |
}) | |
} | |
render() { | |
const {users, queryParams} = this.props | |
const {deleteAction, error} = queryParams | |
return ( | |
<div> | |
{deleteAction === 'progress' ? ( | |
<h4>Deleting user in progress ...</h4> | |
) : ''} | |
{deleteAction === 'success' ? ( | |
<h4>User deleted...</h4> | |
) : ''} | |
<ul> | |
{users.map((user) => ( | |
<li> | |
<User | |
key={user.id} | |
user={user} | |
onDelete={() => this.onUserDelete(user.id)} | |
/> | |
</li> | |
))} | |
</ul> | |
<button> onClick={() => this.onNextUsers()}Next 2</button> | |
{error ? ( | |
<strong style={{background: 'red'}}>Error: {error.message}</strong> | |
) : ''} | |
</div> | |
) | |
} | |
} | |
export default createContainer(UserList, { | |
queryParams: { | |
currentId: 0, | |
error: null, | |
deleteAction: null, | |
deleteUserId: null | |
}, | |
queries: { | |
users({currentId, deleteAction, deleteUserId}) { | |
//How to do thisright way in relay paradigm, without flux actions/stores | |
if(deleteAction === 'progress') { | |
// setState userDeleteBegin | |
return fetch(`/user/${deleteUserId}`, {method: 'DELETE'}) | |
.then(() => { | |
queryParams.error = null | |
queryParams.deleteAction = 'success' | |
//setState userDeleteSuccess | |
//howto change user list without fetching | |
return users | |
}) | |
.catch((err) => { | |
queryParams.error = err | |
queryParams.deleteAction = 'fail' | |
//setState userDeleteFail | |
}) | |
} | |
return fetch(`/users/?from=${currentId}`) | |
.then(data => data.json()) | |
.catch(err => { | |
queryParams.error = err | |
}) | |
} | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// user.js | |
// see https://github.com/RickWong/react-transmit/issues/12 for discussion | |
import React, {PropTypes as p} from 'react' | |
import cn from 'classnames' | |
export default class User extends React.Component { | |
static propTypes = { | |
user: p.shape({ | |
id: p.number, | |
name: p.string | |
}), | |
onDelete: p.func | |
} | |
render() { | |
const {id, user, onDelete} = this.props | |
return ( | |
<div className="user"> | |
Name: <span className={cn('user-name-' + id)}>{user.name}</span> | |
<button onClick={() => onDelete()}>Delete</button> | |
</div> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment