React.js Namespaced Components show nothing - javascript

In the official document React.js, there is a new feature:Namespaced Components from version 0.11.
REF:http://facebook.github.io/react/docs/jsx-in-depth.html
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
var MyFormComponent = React.createClass({ ... });
MyFormComponent.Row = React.createClass({ ... });
MyFormComponent.Label = React.createClass({ ... });
MyFormComponent.Input = React.createClass({ ... });
So, I refer it and write following code to create a component
var MysearchPage=React.createClass({
render:function(){
return (
<div>
</div>
);
}
});
MysearchPage.Title=React.createClass({
render:function(){
return (
<h1>MysearchPage!</h1>
);
}
});
MysearchPage.Search= React.createClass({
render:function(){
return (
<div>
{this.props.searchType}:<input type="text"/>
<button>Search</button>
</div>
);
}
});
var SearchPage=MysearchPage;
var App=(
<SearchPage>
<SearchPage.Title />
<SearchPage.Search searchType="Content"/>
</SearchPage>
);
React.render(
App,
document.getElementById('nuno')
);
Finally,there is no error message,but it show nothing and I cannot see result.I want to know why it show nothing and where is error.
I guess "SearchPage.Title" node do not append to "SearchPage".
Because I change code:
var App=(
<div>
<SearchPage.Title />
<SearchPage.Search searchType="Content"/>
</div>
);
Perhaps, it can get result.
So,I have another problem.
var MysearchPage=React.createClass({
render:function(){
return (
<div>
</div>
);
}
});
What is the difference between the above code and pure HTML tag ? Thank you!

The render function of Mysearchpage just returns an empty div, so you'll have to explicitly render all its component children:
render:function(){
return (
<div>
{this.props.children}
</div>
);
See https://facebook.github.io/react/docs/multiple-components.html

Related

React.js Object.entries().map() not rendering list contents [duplicate]

I am new to React JS, I was testing out some functions in fiddler. I am not sure why I get an error pointing to the map function. I am not able to render the array i defined.
Relevant snippet:
{this.props.data.productSpecs.map(function(productSpec){
<b>Category Name:</b> {productSpec};
})}
Full code:
var productCategory = {
productName: 'SamamgaTV1',
productCategory: 'Television',
productSpecs: ['32inch','black','hd']
};
var ProductComponent = React.createClass({
render: function() {
return( <div>
<h2>Product</h2>
<b>Product Name:</b> {this.props.data.productName}
<h2>Category</h2>
<b>Category Name:</b> {this.props.data.productCategory}
<h2>Specs</h2>
{this.props.data.productSpecs.map(function(productSpec){
<b>Category Name:</b> {productSpec};
})}
</div>);
}
});
ReactDOM.render(
<ProductComponent data={productCategory} />,
document.getElementById('container')
);
First you missed to return, then you must return ONE element.
Here you return a <p> and a TextNode
Moreover you need to provide a unique key.
Try with this :
{this.props.data.productSpecs.map(function(productSpec, i){
return <span key={i}><b>Category Name:</b> {productSpec}</span>;
})}
You need to return value from map handler.
{this.props.data.productSpecs.map(function(productSpec){
return (<span><b>Category Name:</b> {productSpec}<span>);
})}
If you do not want to (or can't in some situations) wrap content in span, you can create & return fragment (very handy)
const createFragment = require('react-addons-create-fragment');
{this.props.data.productSpecs.map(function(productSpec){
return createFragment({
bold: <b>Category Name:</b>,
spec: productSpec,
});
})}
It might be that you are using a string so you have to use the split method and pass in an empty string such as myValue.split('').map();

How to get value from contentEditable in reactjs

I'm fairly new to ReactJS. I am looking to get the value inside a <div> when contentEditable is set to true.
const listResults = this.state.results['1'].map((result) =>
<div key={result.toString()} contentEditable="true">
{result}
</div>
);
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
I am currently outputting a list into pre-filled text-boxes which allows the user to edit them. I am looking to add in a button which once clicked captures the data inside all of the text-boxes. Can anyone point me in a direction on how to capture the changed data.
It may also be worth noting I am using ReactJS on the client side through a CDN.
To get value of editable div:
class App extends React.Component {
constructor(){
super();
this.state = {
arr: [1,2,3,4,5]
}
this.change = this.change.bind(this);
}
change(e, index){
let tmpArr = this.state.arr;
tmpArr[index] = e.target.textContent;
this.setState({arr: tmpArr})
}
render(){
console.log(this.state);
return (
<tr>
{this.state.arr.map((el, index) => <td key={index} id="test" onBlur={(e) => this.change(e, index)} contentEditable="true">{el}</td>)}
</tr>
);
}
}
https://jsfiddle.net/69z2wepo/84647/
One note, you can't return two elements on the same level:
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
It should be wrapped like this:
return (
<div>
<h1> listResults </h1>
<div> {listResults} </div>
</div>
)

Pull data from IndexedDB into array and output it via ReactJS

My actual Javascript code is the following:
var schoolsData = new Array();
myDB.schools
.each(function(school) {
console.log('"' + school.title + '" wird auf den Array gepusht.');
schoolsData.push(new Array(school.title, schools.schoolnumber, school.address, school.principal, school.email, school.creationdate, school.lastupdate, school.comment));
});
var SchoolsRender = React.createClass({
render: function() {
return (
<tr>
{this.props.list.map(function(listValue){
return <td>{listValue}</td>;
})}
</tr>
)
}
});
ReactDOM.render(<SchoolsRender list={schoolsData} />, document.getElementById('schoolsDATA'));
As you can see I am trying to pull data from my local IndexedDB database (I am using dexieJS) and put it via ReactJS into a table element but nothing appears. Where is the point?
Edit: I think the problem is basically that I'm trying to output that 3D array. Is there any simple and elegant solution?
Add another component RowRender to render single row. Modify SchoolsRender component accordingly.
var RowRender = React.createClass({
render: function() {
return (
<tr>
<td>{this.props.title}</td>
<td>{this.props.schoolnumber}</td>
<td>{this.props.address}</td>
<td>{this.props.principal}</td>
</tr>
)
}
});
var SchoolsRender = React.createClass({
render: function() {
return (
<table>
{this.props.list.map(function(listValue,index){
return <RowRender key={index} title={listValue.title} schoolnumber={listValue.schoolnumber} address={listValue.address} title={listValue.address} />;
})}
</table>
)
}
});

nested component in React

I have 3 level nested components. Html structure is like below. C and D's render node/element need to access state and custom function from Main, but C and D are inside B element. I am not sure if this is the best way to structure components. In addition, how do you pass down state and custom functions from Main to grandchildren C and D's render node/element?
<div id="Main">
<div class="A"></div>
<div class="B">
<div class="C"></div>
<div class="D"></div>
</div>
</div>
My attempt:
var Main = React.createClass({
render: function(){
return (
<div className="Main">
<A/>
<B />
</div>
);
}
});
// Putting C, D into B, but C,D both need to access state from Main.
var B = React.createClass({
render: function(){
return (
<div className="B">
<C />
<D />
</div>
);
}
});
var C =....;
var D =....;
React.render(<Main />, document.body)
I am not sure there is a direct way to access the state of child components. But you can use ref.
<Field ref="field1"/>
Then you can use
this.refs.field1.state
Your case:
var B = React.createClass({
render: function(){
return (
<div>
<C ref = "c1"/>
<D ref = "d1"/>
</div>
);
}
});
But this is not recommended as per this link
You may pass the state from Main as props of B
var Main = React.createClass({
getInitialState:function(){
return {mainState:"Main state"}
}
render: function(){
return (
<div>
<A/>
<B mainState={this.state.mainState}/>
</div>
);
}
});
// Putting C, D into B, but C,D both need to access state from Main.
var B = React.createClass({
propTypes:{mainState:React.PropTypes.string}
render: function(){
return (
<div>
{this.props.mainState}// The state from main is received as propps in child component
<C mainState={this.props.mainState}/>// Now youcan access mainState a props of C
<D />
</div>
);
}
});

React.js this.props.data.map() is not a function

I'm messing around with react and trying to parse and render a json object. Right now, I'm just setting it with a hard-coded object for testing and not getting it from an ajax call.
<script type="text/jsx">
var Person = React.createClass({
render: function() {
return (
<div>
<p className="personName"></p>
<p className="personSA1"></p>
<p className="personSA2"></p>
<p className="zip"></p>
<p className="state"></p>
<p className="country"></p>
</div>
);
}
});
var PersonDiv = React.createClass({
render: function() {
var personNodes = this.props.data.map(function(personData){
return (
<Person
personName={personData.person.firstname}
personSA1={personData.person.street1}
personSA2={personData.person.street2}
zip={personData.person.zip}
state={personData.person.state}
country={personData.person.country}>
</Person>
)
});
return (
<div>
{personNodes}
</div>
);
}
});
React.render(
<PersonDiv data={data} />,
document.getElementById('jsonData')
);
I'm setting the data variable with
<script>
var data = "[" + '<%=data%>' + "]";
</script>
The data object is one that I'm creating on the java side of a portlet. I know that the json is valid, because I can use JSON.parse(json) to parse and traverse the string, but I keep getting that map() is not a function.
It appears that your data is not a json object, it is a string. You probably need to run data = JSON.parse(data); to convert your data into an actual javascript object to be able to use it. An easy test for this would be to run
<script>
var data = "[" + '<%=data%>' + "]";
console.log(data);
console.log(JSON.parse(data));
</script>
You should notice the difference.
You are passing result of console.log as first parameter to React.render:
React.render(
console.log("inside render"),
<PersonDiv data={data} />,
document.getElementById('jsonData')
);
It should be like:
console.log("will render");
React.render(
<PersonDiv data={data} />,
document.getElementById('jsonData')
);

Categories