how to render array of component inside Text component in react native? - javascript

I started a chat project in react native. And now I'm having a problem with showing emoji. I got data of message, extract it and save to array. This is an example of message and the array of it
abc :smile: xyz
[
<Text>abc </Text>,
<Image source={{uri:"SMILE_EMOJI_URL"}} />
<Text> xyz</Text>
]
I will create a Text tag and put them all in as nested tags, so I just need to format one time. My expected result
<Text style={MY_STYLE}>
<Text>abc </Text><Image source={{uri:"SMILE_EMOJI_URL"}} /><Text> xyz</Text>
</Text>
How can I do it? Thank you!

your text-Component could look like this:
class ChatMessage extends React.Component {
constructor() {
super();
this.state = {
message: ""
}
}
componentWillMount() {
var localMessage;
for (let i = 0; i < arrayOfEmojiCodes.length; i++) {
if (this.props.message.includes(arrayOfEmojiCodes[i])) {
localMessage = this.props.message.split(arrayOfEmojiCodes[i])[0] + " <img src='"+arrayOfIconImages[arrayOfEmojiCodes[i]]+"' /> " + this.props.message.split(arrayOfEmojiCodes[i])[1];
i = arrayOfEmojiCodes.length;
} else {
localMessage = this.props.message;
}
}
this.setState({message: localMessage});
}
render() {
return(
<div className={this.props.style}>
<p>{this.state.message}</p>
</div>
);
}
}
then you can just call it:
<div className="chat">
{['Message1 :smile', 'message2'].map((value, index) => {
<ChatMessage key={index} message={value} />
})}
</div>
You need to do some modification to your code to fit it your needs, but basically this should make it easier to handle the situation.

Related

Not rendering JSX from function in React

The function is getting the value of a button click as props. Data is mapped through to compare that button value to a key in the Data JSON called 'classes'. I am getting all the data correctly. All my console.logs are returning correct values. But for some reason, I cannot render anything.
I've tried to add two return statements. It is not even rendering the p tag with the word 'TEST'. Am I missing something? I have included a Code Sandbox: https://codesandbox.io/s/react-example-8xxih
When I click on the Math button, for example, I want to show the two teachers who teach Math as two bubbles below the buttons.
All the data is loading. Just having an issue with rendering it.
function ShowBubbles(props){
console.log('VALUE', props.target.value)
return (
<div id='bubbles-container'>
<p>TEST</p>
{Data.map((item,index) =>{
if(props.target.value == (Data[index].classes)){
return (
<Bubble key={index} nodeName={Data[index].name}>{Data[index].name}
</Bubble>
)
}
})}
</div>
)
}
Sandbox Link: https://codesandbox.io/embed/react-example-m1880
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
const circleStyle = {
width: 100,
height: 100,
borderRadius: 50,
fontSize: 30,
color: "blue"
};
const Data = [
{
classes: ["Math"],
name: "Mr.Rockow",
id: "135"
},
{
classes: ["English"],
name: "Mrs.Nicastro",
id: "358"
},
{
classes: ["Chemistry"],
name: "Mr.Bloomberg",
id: "405"
},
{
classes: ["Math"],
name: "Mr.Jennings",
id: "293"
}
];
const Bubble = item => {
let {name} = item.children.singleItem;
return (
<div style={circleStyle} onClick={()=>{console.log(name)}}>
<p>{item.children.singleItem.name}</p>
</div>
);
};
function ShowBubbles(props) {
var final = [];
Data.map((item, index) => {
if (props.target.value == Data[index].classes) {
final.push(Data[index])
}
})
return final;
}
function DisplayBubbles(singleItem) {
return <Bubble>{singleItem}</Bubble>
}
class Sidebar extends Component {
constructor(props) {
super(props);
this.state = {
json: [],
classesArray: [],
displayBubble: true
};
this.showNode = this.showNode.bind(this);
}
componentDidMount() {
const newArray = [];
Data.map((item, index) => {
let classPlaceholder = Data[index].classes.toString();
if (newArray.indexOf(classPlaceholder) == -1) {
newArray.push(classPlaceholder);
}
// console.log('newArray', newArray)
});
this.setState({
json: Data,
classesArray: newArray
});
}
showNode(props) {
this.setState({
displayBubble: true
});
if (this.state.displayBubble === true) {
var output = ShowBubbles(props);
this.setState({output})
}
}
render() {
return (
<div>
{/* {this.state.displayBubble ? <ShowBubbles/> : ''} */}
<div id="sidebar-container">
<h1 className="sidebar-title">Classes At School</h1>
<h3>Classes To Search</h3>
{this.state.classesArray.map((item, index) => {
return (
<button
onClick={this.showNode}
className="btn-sidebar"
key={index}
value={this.state.classesArray[index]}
>
{this.state.classesArray[index]}
</button>
);
})}
</div>
{this.state.output && this.state.output.map(item=><DisplayBubbles singleItem={item}/>)}
</div>
);
}
}
ReactDOM.render(<Sidebar />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
The issue here is ShowBubbles is not being rendered into the DOM, instead (according the sandbox), ShowBubbles (a React component) is being directly called in onClick button handlers. While you can technically do this, calling a component from a function will result in JSX, essentially, and you would need to manually insert this into the DOM.
Taking this approach is not very React-y, and there is usually a simpler way to approach this. One such approach would be to call the ShowBubbles directly from another React component, e.g. after your buttons using something like:
<ShowBubbles property1={prop1Value} <etc...> />
There are some other issues with the code (at least from the sandbox) that you will need to work out, but this will at least help get you moving in the right direction.

I'm unable to retrieve state.Check this code and my output

I have declared a state in class Header.But I can't retrieve that state using {this.state.characters}.Kindly help me to solve.
class Header extends React.Component{
state={
characters: [
{
'name': 'sakthi'
}
]
};
render(){
var style1={
color:'#9876[enter image description here][1]56'
}
return(
<div>
<h1>Hello World !!</h1>
<h4 style={style1}>{this.state.characters}</h4>
</div>
);
}
}
"sakthi" should be printed on my screen.
this.state.characters is an array of objects and it's impossible for React to know how to print, or which property to print. So instead you should use map function to loop thru the array and define how you want it to be
return(
<div>
<h1>Hello World !!</h1>
{
this.state.characters
.map(x => (<h4 style={style1}>{x.name}</h4>))
}
</div>
);
You should represent the array of objects (this.state.characters) like an array of JSX to render it:
class Header extends React.Component {
state = {
characters: [
{
'name': 'sakthi'
}
]
};
renderCharacters = () => this.state.characters.map((c, i) => (
<h4 key={i}>{c.name}</h4>
));
render(){
return(
<div>
<h1>Hello World!!</h1>
{this.renderCharacters()}
</div>
);
}
}

Star Rating Component in react

I am new to react and have started following through the book learning react by Alex Banks and Eve Porcello. I have got to a section that creates a star rating system but at the moment I cant get it working can anyone tell me why? As far as I can tell I have copied the code correctly and everything looks like it should work as intended. Here is the code I have:
const Star = ({ selected=false, onClick=f=>f }) =>
<div className={ (selected) ? "star selected" : "star" } onClick={onClick}>
</div>
Star.propTypes = {
selected: PropTypes.bool,
onClick: PropTypes.func
}
class StarRating extends React.Component {
constructor(props) {
super(props)
this.state = { starsSelected: 0 }
this.change = this.change.bind(this)
}
change(starsSelected) {
this.setState({ starsSelected: starsSelected })
}
render() {
const { totalStars } = this.props
const { starsSelected } = this.state
return(
<div className="star-rating">
{[...Array(totalStars)].map((n,i) =>
<Star
key={i}
selected={i<starsSelected}
onClick={() => this.change(i+1)}
/>
)}
<p>{starsSelected} of {totalStars} stars</p>
</div>
)
}
}
StarRating.propTypes = {
totalStars: PropTypes.number
}
StarRating.defaultProps = {
totalStars: 5
}
When inspecting the components in react-dev-tools it seems that the stars selected prop is always set to false and I cant figure out why. Thanks for any help anyone can offer
It can be 2 things:
this line: {[...Array(totalStars)].map((n,i) =>
You need to pass totalStars as a Number and not a string:
<StarRating totalStars={5} />
or
you are not display anything in your Star component. Try this:
const Star = ({ selected = false, onClick = f => f }) => (
<div className={selected ? "star selected" : "star"} onClick={onClick}>
Star
</div>
);
See a working example:
https://codesandbox.io/s/52ox6wmwwk
The code shared is perfectly fine. Just render something from this code on which the click event would be fired.
const Star = ({ selected=false, onClick=f=>f }) =>
<div className={ (selected) ? "star selected" : "star" } onClick={onClick}>
// Something to render maybe?
</div>
Inject : npm i star-based-rating directly.
For Reference on this react package: star-based-rating
import { FaStar } from "react-icons/fa";
const CreateArray = (length) => [...Array(length)]; // This will create Array with the length provided.
// Star Component
function Star({ selected = false, onSelect }) {
return (
<FaStar color={selected ? "orange" : "lightgray"} onClick={onSelect} />
);
}
// Star Rating component
function StarRating({ totalStars = 5 }) {
const [selectedStars, setSelectedStars] = useState(0);
return (
<>
{CreateArray(totalStars).map((n, i) => (
<Star
key={i}
selected={selectedStars > i}
onSelect={() => setSelectedStars(i + 1)}
/>
))}
<p>
{selectedStars} of {totalStars} // To display selected stars out of total stars
</p>
</>
);
}
function App() {
return <StarRating totalStars={5} />; // This will display 5 stars
}
Working example - Star Rating - CodeSandbox
Your code is working absolutely fine. Check out this link : https://codesandbox.io/s/01wqmzrpjl
Make sure while declaring css classes star is above selected else it will not show the selected style fields if it has same style-field in star className.
Example in my link if I declare selected class above star class then red background (selected style property) is override by grey background (star style property).

Reactjs style component with document.getElementById

Hello i'm trying to highlight the Items, with the same Id. Im using document.getElementById but i don't really know ho to do it. does anyone can help me?
I'm iterating over an Array of Objects from my Database....
return(
<div className='list'>
<Row>
{this.state.cards.map((card) => {
return(<Card
onHover={()=>{
const highlighted = document.getElementById(card.id)
highlighted.style={{backgroundColor: "blue"}}
}}
cardHeading={card.cardHeading} cardDesc={card.cardDesc}
cardPreis={card.cardPreis} cardId={card.id} bewertung={card.cardBewertung}
image={card.cardImage}/>)
})
}
</Row>
</div>
)
.... My GoogleMaps Component:
<Marker onClick={props.show}
position={{ lat: marker.latitude + 0.00201, lng:
marker.longitude + 0.00201}}
id={marker.id}
/>
id={marker.id} and cardId={card.id} are the same and i want to highlight one of them when hovering over them ... thanks in advance.
React gives you the ability for a component to control itself dynamically. So make that Card into a separate component with all of the logic you need using this.setState to control the current style of your Card. I can't test this, but this is the general idea:
return(
<div className='list'>
<Row>
{this.state.cards.map((card) => <CustomCard card={card}/>)}
</Row>
</div>
)
class CustomCard extends Component {
constructor() {
super()
this.state = {
defaultColor: true
}
}
handleClickColorChange() {
this.setState({defaultColor: !this.state.defaultColor})
}
render() {
const {card} = this.props
const customStyle = {
backgroundColor: 'blue'
}
return (
<Card
onHover={() => this.handleClickColorChange()}
style={this.state.defaultColor ? null : customStyle}
cardHeading={card.cardHeading} cardDesc={card.cardDesc}
cardPreis={card.cardPreis} cardId={card.id} bewertung={card.cardBewertung}
image={card.cardImage}
/>
)
}
}

how to properly iterate through array of post objects retrieved through Wp Rest Api in react js

hello :) i am working on wp rest api and react js and i successfully retrieved data from wp rest api and displayed it, but its not the proper way to display data in react. console is showing the error message of ' Each child in an array or iterator should have a unique "key" prop ' . I read the document in react regarding the issue but didn't understood . Here is what i have written so far. Any help would be great thank you
class Home extends React.Component{
componentDidMount(){
const API_URL = 'http://localhost/wordpress/wp-json/wp/v2/posts/';
this.serverRequest = $.get(API_URL, function (result) {
this.setState({
result:result,
loaded:true
});
}.bind(this));
}
constructor(props) {
super(props);
this.state ={result:null,loaded:false};
autoBind(this);
}
render(){
if (this.state.loaded) {
return(
<div>
{this.state.result && <Portfolio data = {this.state.result}/>}
</div>
)
}
return(
<div>loading...
</div>
)
}
}
export default Home;
and the Portfolio component to which prop data is passed renders the data like this which is not the proper way
class Portfolio extends React.Component{
constructor(props) {
super(props);
autoBind(this);
}
render(){
var contents=[];
for (var i = 0; i < this.props.data.length; i++) {
if (this.props.data[i].categories[0] == 5) {
var productImage ={
backgroundImage:'url('+ this.props.data[i].featured_image + ')',
backgroundSize: '100% 100%'
}
contents.push(
<div id="portfolio-product-item" style ={productImage} >
<div id ="portfolio-product-item-details" >
<h3>{this.props.data[i].slug}</h3>
<div dangerouslySetInnerHTML={{__html: this.props.data[i].content.rendered}} />
</div>
</div>
);
}
}
return(
<section className="portfolio">
{contents}
</section>
)
}
}
export default Portfolio;
I haven't went over all of your code, just relating to the "key" error you got.
The issue is here -
contents.push(
<div id="portfolio-product-item" style ={productImage} >
<div id ="portfolio-product-item-details" >
<h3>{this.props.data[i].slug}</h3>
<div dangerouslySetInnerHTML={{__html: this.props.data[i].content.rendered}} />
</div>
</div>
);
The father div with the id of portfolio-product-item should also have an attribute key so the proper way to write it is -
contents.push(
<div key={i} id="portfolio-product-item" style ={productImage} >
<div id ="portfolio-product-item-details" >
<h3>{this.props.data[i].slug}</h3>
<div dangerouslySetInnerHTML={{__html: this.props.data[i].content.rendered}} />
</div>
</div>
);
Have a look at - https://facebook.github.io/react/docs/multiple-components.html#dynamic-children for further info.
To make your Portfolio component cleaner.
I suggest, split the logic and create a separate method from the main render.
class Portfolio extends React.Component{
constructor(props) {
super(props);
autoBind(this);
}
renderPortfolioOption(index, option) {
const { data } = this.props;
if (option.categories[0] == 5) {
var productImage ={
backgroundImage:'url('+ option.featured_image + ')',
backgroundSize: '100% 100%'
}
return(
<div key={index} id="portfolio-product-item" style ={productImage} >
<div id ="portfolio-product-item-details" >
<h3>{option.slug}</h3>
<div dangerouslySetInnerHTML={{__html: option.content.rendered}} />
</div>
</div>
);
}
}
render() {
const { data } = this.props;
if (data.length) return null;
return(
<section className="portfolio">
{ data.map((index, option) => { return this.renderPortfolioOption(index, option); }) }
</section>
)
}
}
export default Portfolio;

Categories

Resources