Skip to content

Instantly share code, notes, and snippets.

@zerkalica
Last active August 29, 2015 14:19
Show Gist options
  • Save zerkalica/a1d2842ee0de9132eff7 to your computer and use it in GitHub Desktop.
Save zerkalica/a1d2842ee0de9132eff7 to your computer and use it in GitHub Desktop.
Understanding react-transmit and relay
//__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
*/
//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
})
}
}
})
// 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