Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class-based React components and composition vs. mixins #117

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fluxxor",
"version": "1.5.4",
"version": "1.6.0-alpha1",
"main": "build/fluxxor.min.js",
"description": "Flux architecture tools for React",
"homepage": "",
Expand Down
4 changes: 1 addition & 3 deletions examples/react-router/app/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ var React = require("react"),
Fluxxor = require("../../../");

var actions = require("./actions.jsx"),
routes = require("./routes.jsx"),
router = require("./router.jsx"),
RecipeStore = require("./stores/recipe_store.jsx");
RouteStore = require("./stores/route_store.jsx");

require("./style.less");

var router = Router.create({routes: routes});

var stores = {
recipe: new RecipeStore(),
route: new RouteStore({router: router})
Expand Down
8 changes: 5 additions & 3 deletions examples/react-router/app/components/empty_view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ var React = require("react"),
Router = require("react-router"),
RouteHandler = Router.RouteHandler;

module.exports = React.createClass({
render: function() {
class EmptyView extends React.Component {
render() {
return <RouteHandler {...this.props} />;
}
});
}

module.exports = EmptyView;
62 changes: 27 additions & 35 deletions examples/react-router/app/components/recipe.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
var React = require("react"),
Router = require("react-router"),
Link = Router.Link,
Fluxxor = require("../../../../");
Link = Router.Link;

var RecipeStore = require("../stores/recipe_store.jsx");

var Recipe = React.createClass({
mixins: [
Fluxxor.FluxMixin(React),
Fluxxor.StoreWatchMixin("recipe")
],

contextTypes: {
router: React.PropTypes.func
},

getStateFromFlux: function() {
var params = this.context.router.getCurrentParams();

return {
recipe: this.getFlux().store("recipe").getRecipe(params.id)
};
},

componentWillReceiveProps: function(nextProps) {
this.setState(this.getStateFromFlux());
},
class Recipe extends React.Component {
constructor() {
super();
this.deleteRecipe = this.deleteRecipe.bind(this);
}

render: function() {
var recipe = this.state.recipe;
render() {
var recipe = this.props.recipe;

if (recipe === RecipeStore.NOT_FOUND_TOKEN) {
return this.renderNotFound();
Expand All @@ -52,23 +35,23 @@ var Recipe = React.createClass({
</p>
</div>
);
},
}

renderIngredient: function(ingredient, idx) {
renderIngredient(ingredient, idx) {
return (
<li key={idx}>
<strong>{ingredient.quantity}</strong> {ingredient.item}
</li>
);
},
}

renderNotFound: function() {
renderNotFound() {
return this.renderWithLayout(
<div>That recipe was not found.</div>
);
},
}

renderWithLayout: function(content) {
renderWithLayout(content) {
return (
<div>
{content}
Expand All @@ -77,15 +60,24 @@ var Recipe = React.createClass({
{" | "}<Link to="add-recipe">Add New Recipe</Link>
</div>
);
},
}

deleteRecipe: function(e) {
deleteRecipe(e) {
if (confirm("Really delete this recipe?")) {
this.getFlux().actions.recipes.remove(this.state.recipe.id);
this.props.onDeleteRecipe(this.props.recipe.id);
} else {
e.preventDefault();
}
}
});
}

Recipe.propTypes = {
recipe: React.PropTypes.object.isRequired,
onDeleteRecipe: React.PropTypes.func.isRequired
};

Recipe.contextTypes = {
router: React.PropTypes.func
};

module.exports = Recipe;
47 changes: 22 additions & 25 deletions examples/react-router/app/components/recipe_adder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@ var t = require("tcomb-form"),
React = require("react"),
Router = require("react-router"),
RouteHandler = Router.RouteHandler,
Link = Router.Link,
Fluxxor = require("../../../../");
Link = Router.Link;

var Recipe = require("../schemas/recipe.jsx"),
RecipeForm = require("../forms/recipe_form.jsx");

var RecipeAdder = React.createClass({
mixins: [
Fluxxor.FluxMixin(React)
],

contextTypes: {
router: React.PropTypes.func
},
class RecipeAdder extends React.Component {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
}

render: function() {
render() {
return this.renderWithLayout(
<div>
<form onSubmit={this.onSubmit}>
Expand All @@ -26,9 +22,9 @@ var RecipeAdder = React.createClass({
</form>
</div>
);
},
}

renderWithLayout: function(content) {
renderWithLayout(content) {
return (
<div>
{content}
Expand All @@ -37,29 +33,30 @@ var RecipeAdder = React.createClass({
{" | "}<Link to="add-recipe">Add New Recipe</Link>
</div>
);
},
}

onSubmit: function(e) {
onSubmit(e) {
e.preventDefault();

var newRecipe = this.refs.form.getValue();
if (newRecipe) {
this.getFlux().actions.recipes.add(
this.props.onAddRecipe(
newRecipe.name,
newRecipe.description,
newRecipe.ingredients,
newRecipe.directions
);
}
},

deleteRecipe: function(e) {
if (confirm("Really delete this recipe?")) {
this.getFlux().actions.recipes.remove(this.state.recipe.id);
} else {
e.preventDefault();
}
}
});
};

RecipeAdder.propTypes = {
onAddRecipe: React.PropTypes.func.isRequired
};

RecipeAdder.contextTypes = {
router: React.PropTypes.func
};


module.exports = RecipeAdder;
70 changes: 32 additions & 38 deletions examples/react-router/app/components/recipe_editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,21 @@ var t = require("tcomb-form"),
React = require("react"),
Router = require("react-router"),
RouteHandler = Router.RouteHandler,
Link = Router.Link,
Fluxxor = require("../../../../");
Link = Router.Link;

var Recipe = require("../schemas/recipe.jsx"),
RecipeForm = require("../forms/recipe_form.jsx"),
RecipeStore = require("../stores/recipe_store.jsx");

var RecipeEditor = React.createClass({
mixins: [
Fluxxor.FluxMixin(React),
Fluxxor.StoreWatchMixin("recipe")
],

contextTypes: {
router: React.PropTypes.func
},

getStateFromFlux: function() {
var params = this.context.router.getCurrentParams();

return {
recipe: this.getFlux().store("recipe").getRecipe(params.id)
};
},

componentWillReceiveProps: function(nextProps) {
this.setState(this.getStateFromFlux());
},
class RecipeEditor extends React.Component {
constructor() {
super();
this.onSubmit = this.onSubmit.bind(this);
this.deleteRecipe = this.deleteRecipe.bind(this);
}

render: function() {
var recipe = this.state.recipe;
render() {
var recipe = this.props.recipe;

if (recipe === RecipeStore.NOT_FOUND_TOKEN) {
return this.renderNotFound();
Expand All @@ -50,15 +34,15 @@ var RecipeEditor = React.createClass({
</p>
</div>
);
},
}

renderNotFound: function() {
renderNotFound() {
return this.renderWithLayout(
<div>That recipe was not found.</div>
);
},
}

renderWithLayout: function(content) {
renderWithLayout(content) {
return (
<div>
{content}
Expand All @@ -67,32 +51,42 @@ var RecipeEditor = React.createClass({
{" | "}<Link to="add-recipe">Add New Recipe</Link>
</div>
);
},
}

onSubmit: function(e) {
onSubmit(e) {
e.preventDefault();

var newRecipe = this.refs.form.getValue();
if (newRecipe) {
this.getFlux().actions.recipes.edit(
this.state.recipe.id,
this.props.onEditRecipe(
this.props.recipe.id,
newRecipe.name,
newRecipe.description,
newRecipe.ingredients,
newRecipe.directions
);

this.context.router.transitionTo("recipe", {id: this.state.recipe.id});
this.context.router.transitionTo("recipe", {id: this.props.recipe.id});
}
},
}

deleteRecipe: function(e) {
deleteRecipe(e) {
if (confirm("Really delete this recipe?")) {
this.getFlux().actions.recipes.remove(this.state.recipe.id);
this.props.onDeleteRecipe(this.props.recipe.id);
} else {
e.preventDefault();
}
}
});
};

RecipeEditor.propTypes = {
recipe: React.PropTypes.object.isRequired,
onEditRecipe: React.PropTypes.func.isRequired,
onDeleteRecipe: React.PropTypes.func.isRequired
};

RecipeEditor.contextTypes = {
router: React.PropTypes.func
};

module.exports = RecipeEditor;
27 changes: 11 additions & 16 deletions examples/react-router/app/components/recipe_list.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
var React = require("react"),
Router = require("react-router"),
RouteHandler = Router.RouteHandler,
Link = Router.Link,
Fluxxor = require("../../../../");
Link = Router.Link;

var RecipeList = React.createClass({
mixins: [Fluxxor.FluxMixin(React), Fluxxor.StoreWatchMixin("recipe")],

getStateFromFlux: function() {
return {
recipes: this.getFlux().store("recipe").getRecipes()
};
},

render: function() {
class RecipeList extends React.Component {
render() {
return (
<div>
<h1>Recipes</h1>
<ul>{this.state.recipes.map(this.renderRecipeLink)}</ul>
<ul>{this.props.recipes.map(this.renderRecipeLink)}</ul>
<div>
<Link to="add-recipe">Add New Recipe</Link>
</div>
</div>
);
},
}

renderRecipeLink: function(recipe) {
renderRecipeLink(recipe) {
return (
<li key={recipe.id}>
<Link to="recipe" params={{id: recipe.id}}>{recipe.name}</Link>
</li>
);
}
});
}

RecipeList.propTypes = {
recipes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
};

module.exports = RecipeList;
Loading