Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx
import { HELLO_WORLD_NAME_UPDATE } from '../constants/helloWorldConstants';
export const updateName = (text) => ({
type: HELLO_WORLD_NAME_UPDATE,
text,
});
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/constants/helloWorldConstants.jsx
/* eslint-disable import/prefer-default-export */
export const HELLO_WORLD_NAME_UPDATE = 'HELLO_WORLD_NAME_UPDATE';
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/reducers/helloWorldReducer.jsx
import { combineReducers } from 'redux';
import { HELLO_WORLD_NAME_UPDATE } from '../constants/helloWorldConstants';
const name = (state = '', action) => {
console.log(action);
switch (action.type) {
case HELLO_WORLD_NAME_UPDATE:
return action.text;
default:
return state;
}
};
const helloWorldReducer = combineReducers({ name });
export default helloWorldReducer;
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/store/helloWorldStore.jsx
import { createStore } from 'redux';
import helloWorldReducer from '../reducers/helloWorldReducer';
const configureStore = (railsProps) => (
createStore(helloWorldReducer, railsProps)
);
export default configureStore;
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/startup/helloWorldApp.jsx
import React from 'react';
import ReactOnRails from 'react-on-rails';
import { Provider } from 'react-redux';
import configureStore from '../store/helloWorldStore';
import HelloWorldContainer from '../containers/HelloWorldContainer';
// See documentation for https://github.com/reactjs/react-redux.
// This is how you get props from the Rails view into the redux store.
// This code here binds your smart component to the redux store.
// railsContext provides contextual information especially useful for server rendering, such as
// knowing the locale. See the React on Rails documentation for more info on the railsContext
const HelloWorldApp = (props, _railsContext) => (
<Provider store={configureStore(props)}>
<HelloWorldContainer />
</Provider>
);
export default HelloWorldApp;
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/containers/HelloWorldContainer.jsx
// Simple example of a React "smart" component
import { connect } from 'react-redux';
import HelloWorld from '../components/HelloWorld';
import * as actions from '../actions/helloWorldActionCreators';
import { updateName } from '../actions/helloWorldActionCreators'
// Which part of the Redux global state does our component want to receive as props?
const mapStateToProps = (state) => ({ name: state.name });
const mapDispatchToProps = (dispatch) => {
return {
onNameUpdate: (name) => {
dispatch(updateName(name))
}
}
};
// Don't forget to actually use connect!
// Note that we don't export HelloWorld, but the redux "connected" version of it.
// See https://github.com/reactjs/react-redux/blob/master/docs/api.md#examples
export default connect(mapStateToProps, mapDispatchToProps)(HelloWorld);
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// app/bundles/HelloWorld/components/HelloWorld.jsx
import React, { PropTypes } from 'react';
const HelloWorld = ({name, onNameUpdate}) => {
return (
<div>
<h3>
Hello, {name}!
</h3>
<hr />
<form >
<label htmlFor="name">
Say hello to:
</label>
<input
id="name"
type="text"
value={name}
onChange={(e) => onNameUpdate(e.target.value)}
/>
</form>
</div>
)
}
HelloWorld.propTypes = {
name: PropTypes.string.isRequired,
onNameUpdate: PropTypes.func.isRequired
}
export default HelloWorld;
@justin808

This comment has been minimized.

Copy link
Owner Author

@justin808 justin808 commented Jan 2, 2017

This is the new proposed React version of the redux generator for react on rails.

Based on https://github.com/EEtancelin/helloWorld-redux-fix/tree/test/client/app/bundles/HelloWorld

and to be used in shakacode/react_on_rails#659

@robwise, @alexfedoseev

  1. Should the reducer use a state of {} rather than a string?
  2. Are so many small files required? Could any be combined?
@robwise

This comment has been minimized.

Copy link

@robwise robwise commented Jan 2, 2017

@justin

  1. No reason to, I tend to write my reducers this way now as well as it's much easier to manage a bunch of combined reducers rather than one monolith reducer
  2. They're not required; this file would work as it's written. However, the question is what your goal is. Do you want to do the simplest thing possible, or do you want to create a skeleton for how one might actually organize their files in the real world?

I don't personally feel the mapDispatchToProps function is necessary, as the shorthand/sugar was added to Redux a while ago that just lets you pass an object with the actions inside and it will automatically bind them to functions of the same name (this shorter way is how we had it previously).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment