Это как-то неудобно, у меня есть идея чтобы вынести List Item (stuff/:id/comp_7/:item_id) и Subitem (stuff/:id/comp_2/:item_id/sublist/:subitem_id) в отдельные контейнеры.
it(`handle action ${patientActions.ON_CHANGE_PATIENT}`, ()=>{
expect(reducer(undefined, {
type: patientActions.PATIENT_INIT_STATE, // тут должно быть patientActions.ON_CHANGE_PATIENT
payload: {
value: '11122',
field: 'patient_ur'
}
})).toEqual({...defaultStates, patient_ur: '11122'})
})
window.sessionStorage.setItem('localCheck', 'true') (или false)
<input
checked={window.sessionStorage.getItem('localCheck') ? true : false } // или 'checked' : false не помню точно,
className="local_checkBox"
type="checkbox"
onChange={() => this.clickOnCheckBoxD(params)}/>
<canvas ref='myCanvas' width={180} height={30} />
.export default class SomeBars extends Component {
componentDidMount() {
this.drawBars(this.props)
}
drawBars(props) {
const { data } = props
const canvas = this.refs.canvas
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
const tempData = data ? data.slice(0,60) : []
tempData.forEach((item,index) => {
ctx.fillStyle = 'rgba(3,169,244,1)'
ctx.fillRect(index*3, 30, 2, -(item/2))
})
}
render() {
return <canvas ref='canvas' width={180} height={30} />
}
}
export default function rootReducer(state = [], action) {
console.log(action);
if(action.type === 'BUTTON_CLICK'){
return[
...state,
action.book
]
store.dispatch(state) // выкинуть отсюда.
}
return state;
}
export default class Inputs extends Component {
constructor(props) {
super(props)
this.onAuthorChange = this.onAuthorChange.bind(this)
this.onNameChange = this.onNameChange.bind(this)
this.takeVal = this.this.takeVal.bind(this)
this.state = {
author: '',
name: '',
}
}
onAuthorChange(e) {
this.setState({ author: e.target.value })
}
onNameChange(e) {
this.setState({ name: e.target.value })
}
takeVal() {
this.props.addItem({ // имя, под которым вы передали свой экшен в качестве пропса от родителя
author: this.state.author,
name: this.state.name,
})
}
render() {
const {author, name} = this.state
return (
<div className="app__enter">
<div className="inputs-bock">
<input onChange={this.onAuthorChange} className="inputs-book__author" placeholder="Автор" type="text" value={author}/>
<input onChange={this.onNameChange} className="inputs-book__name" placeholder="Название" type="text" value={name}/>
</div>
<div className="button-wrap">
<button onClick={this.takeVal}>Добавить книгу</button>
</div>
</div>
)
}
}
import React, { Component } from 'react'
import Inputs from '../components/Inputs'
import { connect } from 'react-redux'
import {
addItem,
} from '../../actions/UserActions'
class InputsContainer extends Component {
render() {
return <Inputs addItem={this.props.addItem} />
}
}
const mapStateToProps = (state) => ({})
const mapDispatchToProps = (dispatch) => ({
addItem: (params) => dispatch(addItem(params)),
})
export default connect(mapStateToProps, mapDispatchToProps)(InputsContainer)
showInfoPage(e) {
const id = e.currentTarget.id
// далее нужно вызвать сам переход
// я делаю это через push из react-router-redux ( import { push } from 'react-router-redux' )
// можно прокинуть через dispatch
dispatch(push('/information/'+id))
//конечно, у вас dispatch скорее всего будет прокинут из props, поэтому финальный вариант
this.props.dispatch(push('/information/'+id))
}
<tr onClick={showInfoPage} id={infos.id}>
<td key={infos.id}>{infos.id}</td>
<td key={infos.about}>{infos.about}</td>
</tr>
...
let AppSmallRedux = connect(
(store) => ({ data: store.reducerAppSmall }), // (1)
dispatch => ({
update: () => dispatch({ type: "UPDATE_AppSmall" })
})
)(AppSmall);
...
let AppRedux = connect(
(store) => ({ data: store.reducerApp }), // (2)
dispatch => ({
update: () => dispatch({ type: "UPDATE_App" })
})
)(App);
...
...
const request = require('superagent-bluebird-promise')
...
export function addProduct(formData) {
return dispatch => {
dispatch({ type: PRODUCT_ADD_REQUEST })
if (formData.image) {
return request.post(`${API_ROOT_V1}/api/v1/products/add`)
.field('name', formData.name)
.field('price', formData.price)
.field('description', formData.description)
.field('providerId', formData.providerId)
.attach('image', formData.image, formData.image.name) // добавление картинки
.then(...) // здесь дальнейшая обработка в случае успеха
} else { // кейс, когда у товара нет картинки
return request.post(`${API_ROOT_V1}/api/v1/products/add`)
.send(formData)
.then(...)
}
}
}
...
// (обработчик сабмита формы)
this.props.addProduct({
name,
price,
description,
image: findDOMNode(this.refs.image).files[0], // (забираю картинку)
providerId: this.props.providerId,
})
...
// непосредственно кнопка загрузки файла в форме
<div className='form-group'>
<input
id='productImage'
type='file'
name='image'
placeholder='Image'
onChange={this.handleChange}
value={this.state.image}
data-field-name='image'
ref='image' />
<p>Load product image</p>
</div>
...