I've attached the relevant code in the bottom
Hey guys, I've created a file with multiple button components, and a function component that should render 2 buttons according to the props it receives (for example, render & when in homepage, and render & when in a different page).
The concept being it is to create a single component that will always be rendered in my Layout HOC and will know which buttons to display based on the page url.
The way I tried realizing that buttons function, is by creating a variable that will get the two proper buttons assigned to in a switch case based on the current url, and return that variable.
I try assigning a JSX element made of a React.Fragment that has the 2 relevant button components inside it, but I get an error saying my needs to have a corresponding closing tag..?
I'd really appreciate an explanation as for why it happens, and what would be a proper approach for my use case.
Thanks a lot...!!!
My layout HOC:
const Layout = props => (
<Grid fluid>
<div style={layoutStyles}>
{props.children}
<FloatingButtons page={props.page.pathname} />
</div>
<div style={layoutStyles}>
{ showFooter(props.page.pathname, pagesToShow) && <Footer /> }
</div>
</Grid>
This is my FloatingButtons component:
const FloatingButtons = (props) => {
const { page } = props;
let buttons;
let simplifiedUrl = page.slice(page.lastIndexOf('/') + 1);
switch (simplifiedUrl) {
case 'home':
buttons =
<React.Fragment> ***// Here is where I get the error***
<MenuFloatingBtn {...props} />
<ShareFloatingBtn {...props} />
<React.Fragment/>
break;
case 'otherPage':
buttons = 'etc'
break;
default:
break;
}
return buttons;
};
Instead of declering let buttons.
You can return directly the answer. with no needed for break.
Than the switch will look like this:
switch (simplifiedUrl) {
case 'home':
return (
<React.Fragment> ***// Here is where I get the error***
<MenuFloatingBtn {...props} />
<ShareFloatingBtn {...props} />
<React.Fragment/>);
case 'otherPage':
return 'etc';
default:
return null;
}
Good luck!
Related
//I Want to add some of the Icons in my Project to make a tik-tak-toe application so wrote this code, simply made an Icon function, and switch statement to whether It will circle, cross or pen ```
const Icon = ({ name }) => {
return (
<div>
switch (name){
case 'crcle': return
return<FaRegCircle className="Icons" />
case 'cross':
return<FaTimes className="Icons" />
default:
return<FaPen className="Icons" />
</div>
);
};
export default Icon;
[enter image description here][1]
I'm new in ReactJs, I want to build a tik-take-toe game using react but whenever I placed logic in Icon.js file of the component folder, I got an error which shows a red underline of my switch case that "expression expected." in case statement in switch, Surprised to see even I write the same exact code which tutor show in the tutorial though I got error ```
The switch statement cannot be inlined here.
You need to create a function and put the switch statement inside.
And any JavaScript code inside JSX should be wrapped with {}.
const Icon = ({ name }) => {
const renderIcon = () => {
switch (name) {
case 'crcle':
return <FaRegCircle className="Icons" />
case 'cross':
return <FaTimes className="Icons" />
default:
return <FaPen className="Icons" />
}
}
return (
<div>
{renderIcon()}
</div>
);
};
export default Icon;
I have tried finding the answer to this on StackOverflow and there are some related posts (e.g. React Child Component Not Updating After Parent State Change) but I want to understand why this is not working...
I have a React application that will display a layout of character cards (that is, each card displays a different character). It uses a child component, CharacterBoard, that lays out the CharacterCards, which would be a grandchild component. I pass the characters down from the App to the CharacterBoard as props, and CharacterBoard in turn maps these out the CharacterCards.
The problem is that I want the state of the character to change when I click on one of them. Specifically, I want the revealed field to change. However, even though the state change is reflected in the array of characters in the App (that is, the revealed field changes correctly), and the change is reflected in the array of characters in CharacterBoard, but not in CharacterCard. In fact, my mapping does not seem to be called at all in CharacterBoard when the props change.
Do I need to use something like getDerivedStateFromProps in CharacterBoard and set the state of that component and then use the state to map the values down to CharacterCard? If so, why?
In short (tl;dr), can you pass props on down through the component chain and map them out along the way and still have all changes reflected automatically?
Thanks for any guidance.
If it helps, the render method of my App is
render() {
const {state: {characters}} = this
return (
<div>
<header>
</header>
<main>
<CharacterBoard
onCardSelected={this.onCardSelected}
rowSize={logic.ROW_SIZE}
characters={characters}
cardSize={this.CARD_SIZE}/>
</main>
</div>
);
}
that of CharacterBoard is
render() {
const {props: {characters, rowSize, cardSize,onCardSelected}} = this
const rowUnit = 12 / rowSize
const cardLayout = characters
.map((character, i) => (
<Col xs={6} sm={rowUnit} key={character.name}>
<CharacterCard
onCardSelected = {onCardSelected}
key={i + Math.random()}
character={character}
cardSize={cardSize}
/>
</Col>
)
)
return (
<div>
<Container>
<Row>
{cardLayout}
</Row>
</Container>
</div>
)
}
and finally CharacterCard has this render method
render() {
const {props: {character, cardSize}} = this
const {thumbnail, revealed} = character
const imgURL = `${thumbnail.path}/${cardSize}.${thumbnail.extension}`
const topCardClass = classNames('characterCard__card-back', {'characterCard__card-back--hidden': revealed})
console.log(revealed)
return < a href="/#" onClick={this.onCardSelected}>
<div className='characterCard__card'>
<div className={topCardClass}>
<img src="/images/card_back.png" alt=""/>
</div>
< div className='characterCard__card-front'>< img alt=''
src={imgURL}/>
</div>
</div>
</a>
}
Doh! A simple forgetting to setState in App. Knowing that it should work made me go back through the code one more time and see that, indeed, it was a stupid error on my part.
Problem
I am using a flatlist in react native, and want to compare to variables in the flatlist, and render a text component if the two variables are equal, but render nothing if they are not. I've tried many methods of doing this, but they nothing has worked. I would love some help figuring out a way to do this! Thank you.
Couple ways that spring to mind straight away. Ill just assume what you are trying to compare but you can switch these variables out for whatever you please. First thing you could do is have your text be conditional inside of your Text component, EG
<Text>{this.state.variable == this.props.stuff ? "RENDER TEXT" : ""}</Text>
or, if you want to emit the Text component when variables are not equal, have a function inside of your class that will return the Text component conditionally
renderMessage = () => {
if(this.state.variable == "stuff"){
return(
<Text>They were equal</Text>
);
}else{
return(
<View></View> // OR WHATEVER YOU WANT HERE
);
}
}
...
//Then in your render function
....
<View style = {styles.whatever}>
{this.renderMessage()}
</View>
just compare your data in renderItem method accordingly
<FlatList
data={this.props.data}
renderItem={this._renderItem}
/>
_renderItem = ({item}) => (
if(item=='somthing'){
return <Text> your test </Text>
}else{
return <Text>some other text</Text>
}
);
if you want to compare your text in component then
<View>
{
item.data == 'somthing'
?
<Text>if</Text>
:
<Text>else</Text>
}
</View>
We are trying to scroll to a specific component when the user closes another component.
Our example is very similar to that down below, taken from https://reactjs.org/docs/refs-and-the-dom.html#exposing-dom-refs-to-parent-components
function CustomComponents(props) {
const items = [1,2,3,4].map((x, i) => return (
<div ref={props.inputRef} key={i}>
x + hello
</div>
)
return (
<div>
{ items }
</div>
);
}
function Parent(props) {
return (
<div>
<CustomComponents inputRef={props.inputRef} />
</div>
);
}
class Grandparent extends React.Component {
render() {
return (
<Parent
inputRef={el => this.inputElement = el}
/>
);
}
}
We are rendering a big list of cards and want to be able to scroll to a specific card by calling this.refs[elem].scrollIntoView()
But our problem is that calling this.refs returns an empty object at all levels, and so we are unable to attach to a specific element and then fire it when the user arrives back to view this component.
Would like some help on how one would go about solving this issue.
Where are you trying to call this.refs[elem].scrollIntoView()? You should be working with refs inside componentDidMount or componentDidUpdate, not inside the render method.
I've solved my specific issue by providing an if statement written below in my Grandparent component.
inputRef={el => {
if (el && el.id == this.state.selectedBuildingRef) {
this.myelement.scrollIntoView();
window.scrollBy(0, -65);
}
}}
Let's assume i have a react component class that displays a modal dialog on a click of a button.
it can be created like this (in jsx):
<Modal text={"some text"}/>
Now, I have a bunch of component classes (let's call them Panels) that all have a function called getMessage, and i'd like the same behavior in all of these components: the modal dialog should show the string that returns from the call to getMessage.
the straight forward way to do this would be to include
<Modal text={this.getMessage()}/>
in the render() function for each such component.
Now, let's say that there is a bit more logic involved. for example, i would only like to render this component if getMessage is defined and does not return null.
Now this is starting to look like this:
var Panel1 = React.createClass({
getMessage: function() {return 'wow';},
render: function() {
var modal = null;
if (this.hasOwnProperty('getMessage' && this.getMessage() !== null) {
modal = <Modal text={this.getMessage()}/>
}
return (
<div>
{modal}
...all other stuff done in panel
</div>
);
}
});
This is starting to become cumbersome because I need to have this logic for each and every component class I define.
How can I achieve DRYness in this scenario so that i don't have to repeat this?
One way would be to define a utility function that contains this logic, let's call it displayModalIfNeeded and the call it from render. this now looks like this:
return (
<div>
{displayModalIfNeeded.call(this)}
....all other stuff needed in Panel
</div>
);
And now for my actual question (sorry for the long exposition):
Let's say that i have a parent component called <Dashboard> which has all panels as its childern:
<Dashboard>
<Panel1>
<Panel2>
<Panel3>
</Dashboard>
Is there something i can write in the implementation of Dashboard that will entirely remove the need to specify anything about these modal components in each Panel?
meaning the the Panel1 implementation can now just be
<div>
...all other stuff done in panel
</div>
and when it's rendered as a child of Dashboard it will have that modal dialog and accompanying logic.
I suggest using a wrapper component with the children prop. Your parent component would look like this:
<Dashboard>
<ModalWrapper text={msg1}>
<Panel1 />
</ModalWrapper>
<ModalWrapper text={msg2}>
<Panel2 />
</ModalWrapper>
<ModalWrapper text={msg3}>
<Panel3 />
</ModalWrapper>
</Dashboard>
Now all your conditional logic can be placed in ModalWrapper. Where your question has "....all other stuff needed in Panel", use this.props.children. e.g.
var ModalWrapper = React.createClass({
render: function () {
var text = this.props.text;
return (
<div>
{text ? <Modal text={text} /> : null}
{this.props.children}
</div>
);
}
});