I have a JSX file like this:
var Home = React.createClass({
render: function() {
return (
<Test>
...
var Test = React.createClass({
render: function() {
...
module.exports = Home;
But I cant manage that both functions load, I guess I have to add Test to module.exports, but I couldn't find a method that worked.
If you require("home.jsx") it will automaticaly load and render your Test component inside Home.
It would be better to separate those components in defferent files, that will help you to manage components when your app will be too large.
test.jsx
module.exports = React.createClass({
render: function() {
return <div>Test</div>
}
})
home.jsx
var Test = require('./test.jsx');
module.exports = React.createClass({
render: function() {
return <div>
<Test>
</div>
}
})
Of course you are also able to do something like #Mukesh Sharma answer.
Thanks
Hope it helps you.
var Home = React.createClass({
render: function() {
return (
<Test>
...
var Test = React.createClass({
render: function() {
...
module.exports = {
"Home": Home,
"Test": Test
}
Related
For multiple React component , I want to inject a common code to the life cycle of React.
Is there something good way?
var ComponentA = React.createClass({
componentWillMount: function () {
},
componentDidUpdate: function(){
//inject common code
},...
var ComponentB = React.createClass({
componentWillMount: function () {
},
componentDidUpdate: function(){
//inject common code
},...
Do you mean just sharing functions across multiple components? If so, you can just keep them in a separate file and import them where ever you need to:
// common js
function hello() {
console.log('hello');
}
module.exports = hello;
// your component
var hello = require('./common');
var ComponentA = React.createClass({
componentDidUpdate: function(){
hello();
},//...
http://www.webpackbin.com/Nk80m1x_W
Another thing you can do is create a wrapper (higher order) component:
var WrapperComponent = React.createClass({
componentDidUpdate: function() {
// code you want to inject.
},
render: function () {
return(<div>{this.props.children}</div>);
}
});
then whenever you need to use a component with that lifecycle, you can do this in jsx:
<WrapperComponent>
<ComponentA />
</WrapperComponent>
Though higher order component approach suggested by #jzm is better, you could also use mixins:
var myMixin = {
componentWillMount: function(){
//common code
},
componentDidUpdate: function(){
//common code
}
};
var ComponentA = React.createClass({
mixin: [myMixin]
});
var ComponentB = React.createClass({
mixin: [myMixin]
})
I am using browserify, gulp and reactjs together,
I have the following app.js contains my other scripts;
var React = window.React = require('react');
var Signup = require('./ui/Signup');
var Login = require('./ui/Login');
`Signup.js``
var React = require('react');
var signupNode = document.getElementById('signup');
var SignupApp = React.createClass({
render: function(){
return (<Signup/>)
}
});
var Signup = React.createClass({
render: function(){
return (
<div>
<div classNameName="form-block center-block">
<h2 classNameName="title">Üye Ol</h2>
<SignupForm/>
</div>
</div>
)
}
});
var SignupForm = React.createClass({
render: function(){
return (<div className='form-horizontal'>
hede
</div>)
}
});
React.renderComponent(<SignupApp/>, signupNode);
module.exports = Signup;
and Login.js
/** #jsx React.DOM */
var React = require('react');
var loginNode = document.getElementById("login");
var LoginApp = React.createClass({
render: function(){
return (<Login></Login>)
}
});
var Login = React.createClass({
render: function(){
return (
<div>
<div className="form-block center-block">
<h2 className="title">Giriş Yap</h2>
<LoginForm/>
</div>
</div>
)
}
});
var LoginForm = React.createClass({
render: function(){
return (<div className="form-horizontal">
hede
</div>
)
}
});
React.renderComponent(<LoginApp/>, loginNode);
module.exports = Login
I want those modules to be ready according to their dom elements for different templates which i am both including app.js,
But I am having Invalid Violation Register Component Target container is not a DOM element. error because Login Modal can not find signup id on DOM. Any ideas?
This is fixed, when i made a custom routing like below;
if (window.location.pathname.indexOf('login') > -1) {
React.renderComponent(<Login/>, loginNode);
}
if (window.location.pathname.indexOf('signup') > -1) {
React.renderComponent(<Signup/>, signupNode);
}
if (window.location.pathname.indexOf('new_post') > -1) {
React.renderComponent(<NewPost/>, newPostNode);
}
if (window.location.pathname.indexOf('home') > -1) {
React.renderComponent(<Home/>, HomeNode);
}
I'm fairly new at react.js, so any help is greatly appreciated.
I have this: https://jsfiddle.net/rzjyhf91/
Wherein I have made 2 components: an image and a button.
The goal is to remove the image with a click of the button, I use unmountComponentAtNode for that, but it does not work:
var App = React.createClass({
render: function() {
return (
<div><MyImage /><RemoveImageButton /></div>
);
}
});
var MyImage = React.createClass({
render: function() {
return (
<img id="kitten" src={'http://placekitten.com/g/200/300'} />
);
}
});
var RemoveImageButton = React.createClass ({
render: function() {
return (
<button onClick={this.handleClick}>remove image</button>
)
},
handleClick: function(){
React.unmountComponentAtNode(document.getElementById('kitten'));
}
});
React.render(<App />, document.body);
How can I remove a react component from another component?
Well, it seems you should rethink how the display control is handled. React is all about isolated components, and so, you shouldn't be unmounting a component that is mounted by a parent component. Instead, you should use a callback passed down through props to accomplish something like that.
Your actual implementation will depend on your use case, but an updated version of your example that works is at: https://jsfiddle.net/nt99zzmp/1/
var App = React.createClass({
render: function() {
var img = this.state.showImage ? <MyImage /> : '';
return (
<div>{img}<RemoveImageButton clickHandler={this.removeImage} /></div>
);
},
getInitialState: function() {
return {
showImage: true
};
},
removeImage: function() {
this.setState({ showImage: false });
}
});
var MyImage = React.createClass({
render: function() {
return (
<img id="kitten" src={'http://placekitten.com/g/200/300'} />
);
}
});
var RemoveImageButton = React.createClass ({
render: function() {
return (
<button onClick={this.props.clickHandler}>remove image</button>
)
}
});
React.render(<App />, document.body);
Basically removing a component doesn't make sense in React, you probably still thinking jQuery ways, basically in all modern and new JavaScript libraries including React, you should manage your component using state or a route to handle these things, deleting an element or component is not a good way to do these things in React or Angular for example.
For example you can have a boolean in this case and if it's true, show your image, otherwise hide it, or even return a different element in your component.
So in this case, you have a component which will return differently depends on props or state... something like this:
////
var MyImage = React.createClass({
render: function() {
if(this.state.showImage) {
return (
<img id="kitten" src={'http://placekitten.com/g/200/300'} />
);
} else {
return<p>no image!</p>;
}
}
});
////
In this example, if you set this.state.render = false, the component will be removed from DOM:
render() {
const { render } = this.state;
if (render === false) return null;
return (<p>I am here as long as render isn't false</p>);
}
In React JSX it does not appear to be possible to do something like this:
render: function() {
return (
<{this.props.component.slug} className='text'>
{this.props.component.value}
</{this.props.component.slug}>
);
}
I get a parse error: Unexpected token {. Is this not something React
can handle?
I'm designing this component so that under the hood, the values stored in this.props.component.slug will contain valid HTML elements (h1, p, etc.). Is there any way to make this work?
You should not put component slug in curly braces:
var Hello = React.createClass({
render: function() {
return <this.props.component.slug className='text'>
{this.props.component.value}
</this.props.component.slug>;
}
});
React.renderComponent(<Hello component={{slug:React.DOM.div, value:'This is my header'}} />, document.body);
Here is a working fiddle: http://jsfiddle.net/kb3gN/6668/
Also, you can find JSX Compiler helpful for debugging these kind of errors:
http://facebook.github.io/react/jsx-compiler.html
As nilgun previously pointed out, the component slug should not be wrapped in curly braces.
If you decide to store it in a variable, make sure it starts with a capital letter.
Here is an example:
var Home = React.createClass({
render: function() {
return (
<div>
<h3>This is an input</h3>
<CustomComponent inputType="input" />
<h3>This is a text area</h3>
<CustomComponent inputType="textarea" />
</div>
);
}
});
var CustomComponent = React.createClass({
render: function() {
// make sure this var starts with a capital letter
var InputType = this.props.inputType;
return <InputType />;
}
});
React.render(<Home />, document.getElementById('container'));
Here's a working fiddle: https://jsfiddle.net/janklimo/yc3qcd0u/
If your intention is to inject the actual component rendered, you can do something like this, which is very convenient for testing, or whatever reason you would want to dynamically inject components to render.
var MyComponentF=function(ChildComponent){
var MyComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="MyComponent">
<ChildComponent></ChildComponent>
</div>
);
}
});
return MyComponent;
};
var OtherComponentF=function(){
var OtherComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="OtherComponent">
OtherComponent
</div>
);
}
});
return OtherComponent;
};
var AnotherComponentF=function(){
var AnotherComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="AnotherComponent">
AnotherComponent
</div>
);
}
});
return AnotherComponent;
};
$(document).ready(function () {
var appComponent = MyComponentF(OtherComponentF());
// OR
var appComponent = MyComponentF(AnotherComponentF());
// Results will differ depending on injected component.
ReactDOM.render(React.createElement(appComponent), document.getElementById("app-container"));
});
Edit: Maybe you forgot to add /** #jsx React.DOM */ at the beginning of js?
You can use React.DOM though:
render: function() {
return React.DOM[this.props.component.slug](null, this.props.component.value);
}
http://jsbin.com/rerehutena/2/edit?html,js,output
I am not a React expert, but I think every component should be construct with a specific tag at the beginning. So it could present a clear purpose itself.
The solution for me was to assign the imported Component to a variable(with CapitalCase) and then render that variable.
Example:
import React, { Component } from 'react';
import FooComponent from './foo-component';
import BarComponent from './bar-component';
class MyComponent extends Component {
components = {
foo: FooComponent,
bar: BarComponent
};
//this is the most important step
const TagName = this.components.foo;
render() {
return <TagName />
}
}
export default MyComponent;
What is the standard way of setting React Component states based on routes? I have the following React/Backbone example:
var myApp = React.createClass({
render: function() {
return (
<div className={this.state}></div>
);
}
})
var App = Backbone.Router.extend({
routes: {
"": "home",
"create": "create"
}
});
var app = new App();
app.on('route', function(page) {
// How do I set state on myApp??
})
React.renderComponent(<myApp />, document.body);
Backbone.history.start();
I believe I need to be able to set the state of myApp from outside, but how? I can’t find any examples on this.
Or maybe I’m thinking in the wrong direction here, is there a better way of organizing routes together with React?
i have no idea what the general solution is, but what I, a bit simplified, did is
var App = Backbone.Router.extend({
routes: {
"": "home",
"create": "create"
}
});
var myComponent = false
function loadOrUpdateComponent(urlState) {
if (!myComponent) {
myComponent = <MyApp urlState={urlState}/>
React.renderComponent(myComponent, document.body);
} else {
myComponent.setProps({urlState:urlState})
}
}
var app = new App();
app.on('route', function(page) {
loadOrUpdateComponent(page)
})
Backbone.history.start();
So the actual answer to your question is to use .setProps(newProps) on a previously rendered component. i load the component in the event handler because else you get a race condition between renderComponent and setProps wich might lead to bad things.
Edit:
Ive since updated my route handling, i now simply do
router.on('list', function() {
React.renderComponent(<Component data={someData} />, mountPoint)
})
router.on("details", function(id) {
React.renderComponent(<Component data={someData} selected={id} />, mountPoint)
})
router.on("extra-details", function(id) {
React.renderComponent(
<Component data={someData} selected={id}>
<SpecificExtraComponent />
</Component>
, mountPoint
)
})