Newbie to React : Any help would be greatly appreciated - reactjs

I am doing a code challenge and am very new to React. I am used to hard coding things, and I need to loop in data from a JS file. I am familiar with HTML and CSS so styling will be no problem, but how I can pull in the data from the menu items without hardcoding. Below are links to what I have in the project files as well as a reference as to what it should look like. Thanks!
[1]: https://i.stack.imgur.com/JtE4X.png
[2]: https://i.stack.imgur.com/n412K.png
[3]: https://i.stack.imgur.com/ZVSl2.png

Here's a simplified example
Interactive sandbox
https://codesandbox.io/s/lucid-lovelace-kr6rr?fontsize=14&hidenavigation=1&theme=dark
Here's the code:
function myComponent() {
// Here's your data
// You'll probably want to set this to state after fetching it
// (It doesn't need to be in a const)
const myList = [
"https://i.stack.imgur.com/JtE4X.png",
"https://i.stack.imgur.com/n412K.png",
"https://i.stack.imgur.com/ZVSl2.png"
];
// map over your data
// here we are rendering an html img for each item
// and we give each a key to help react keep a record of what is has rendered
return (
<div>
{myList.map(url => <img src={url} key={url} />)}
</div>
)
}
Hope it helps!

On line 19, try
let menuItems = this.state.menuItems.map((item) => {
<MenuItem name={item.name} img={item.imageName} price={item.details.price} />
}
Then in your return,
<div id="combo-header">
<h1>Combo Meals</h1>
{menuItems}
</div>
You can also choose to loop within your render instead of assigning to its own menuItem variable.
<div id="combo-header">
<h1>Combo Meals</h1>
{this.state.menuItems.map((item) => {
<MenuItem name={item.name} img={item.imageName} price={item.details.price} />
}}
</div>
Note that the second option requires the javascript to be wrapped in {} so that you can write javascript directly in the JSX.
After this, you'd write a MenuItem component that would intake the props above.
You will also have to perform a check that the array is not empty before mapping over it, or there will be errors.

Related

How to created a optgroup in select v4 mui component by mapping over an array to avoid code duplication?

I am trying to create a dynamic v4 mui select , that will render value and options related to that value , the current issue is since I am mapping in a div, the current value is undefined , please check the code sandbox example... how to make this value identifiable by the handle change ?... technically there is no way to catch the pressed on value in the dropdown... since it has to be on the surface and by mapping I am pushing it a one level down..
{arr?.map((option, i) => (
<div key={i}>
<ListSubheader>{option}</ListSubheader>
<MenuItem key={option}>{objectData[option]}</MenuItem>
</div>
))}
Code Sandbox
Typically in React, you would solve an issue like this by wrapping the elements in a <Fragment> (<>...</>). However, the <Select> MUI component does not accept this, so return an array containing each component from your map callback instead.
{
arr?.map((option, i) => [
<ListSubheader>{option}</ListSubheader>,
<MenuItem
key={option}
value={objectData[option]}
>
{objectData[option]}
</MenuItem>,
]);
}
Hope this helps.
Links:
You can read more on <Fragment> (<>...</>) on the React documentation, here.
You can also read more on the MUI <Select> component, here.

Background Image not showing in react production app, showing normally in development

I have a component 'Countries' that shows a list of countries. It loops a JSON object with country names and paths to their flag images, then passes those as props to a Component 'SingleCountry' who in turn displays them.
Relevant part of component 'Countries':
//this is inside return() statement
<div className="country-list">
{
_.map(countries[region], (value, key)=>{
const picture = require(`../../img/flags/${value.picPath}`);
return(
<SingleCountry name={value.name} picture = {picture} countryId={key} key={key}
region={region}/>
)
})
}
</div>
Relevant part of the component 'SingleCountry':
//this is inside return() statement
<div className="single-country">
<div className="flag" style ={{backgroundImage: `url(${picture})`}}></div>
<div className="country-name">{name}</div>
</div>
</div>
The above is working well in development. You can see a picture here (along with the inspection):
https://imgur.com/CirT4YW
However, it is not working in production. You can see a picture here: https://imgur.com/nuX7rKu
Any help is appreciated.

React (not sure where a variable comes from)

I am new to React and am trying to understand React-Popper. This is some code from
https://www.npmjs.com/package/react-popper
Where are the values for 'ref', 'style', 'placement' and 'arrowProps' coming from and how would I edit them? I understand that you can use this.props and attributes to pass values to Components but i dont understand where the values to be inserted into the function is coming from.
import { Manager, Reference, Popper } from 'react-popper';
const Example = () => (
<Manager>
<Reference>
{({ ref }) => (
<button type="button" ref={ref}>
Reference element
</button>
)}
</Reference>
<Popper placement="right">
{({ ref, style, placement, arrowProps }) => (
<div ref={ref} style={style} data-placement={placement}>
Popper element
<div ref={arrowProps.ref} style={arrowProps.style} />
</div>
)}
</Popper>
</Manager>
);
What you're seeing here is an arrow function being combined with destructuring assignment and React Render Props. So it's a lot in one code example.
From your question, I think what's confusing you most is the destructuring assignment. So here is an example which I hope will help you:
var foo = ({a, b}) => a + b;
var x = {
a: 1,
b: 2
};
console.log(foo(x));
# Output is 3
This is because destructuring assignment assigns the values from the object into the variables a and b as if they were function parameters. The same thing is happening with the props object on the React components and that's why you don't see props.ref, etc.
They are render props for the Popper component. They are all parameters of the render prop function defined in the Popper file you can find on the GitHub for this package. I'm not familiar with this specific library, but basically they are being passed to that function, and they need to be there as it's defined or it will throw an error. You should be able to compute your own values for styles and whatnot but again I'm not familiar with this package.

`rexxars/react-markdown` plugin usage or alternative for rendering React markdown

I'm trying to render some html, stored in a DB, and put a component inside.
It'd look like this:
import ReactMarkdown from 'react-markdown/with-html';
const inlineCode = (props) => <Gist id={props.value} />;
const source = '`7df0c9a5d794504a28bd3256b7bf5c4f` <p>asdasdasd</p><h1>title</h1>';
ReactMarkdown is used like this:
<ReactMarkdown source={source} renderers={{ inlineCode }} escapeHtml={false} />
The result is is rendered properly and the block is also, but isn't, the contents are outside of the block.
If I wrap the whole source with a <div>, the <Gist/> is rendered as text and <p>/<h1> are rendered properly.
What am I missing? I'm trying to store html with custom components inside, <Gist/> is just an example. Suggestions for a (more) suitable library are also welcome. Example ideal source I'd like to store in a db and then render in a React component:
<div>
<p>
<CustomReactComponent/>
<br/>
test
</p>
<Gist/>
</div>
Okay I found this lib: https://github.com/probablyup/markdown-to-jsx
If your source looks like:
const source = `<gist id="yourIdHere" /> <h1>asdasdasd</h1>`;
<Markdown
options={{
overrides: {
gist: {
component: renderGist,
},
},
}}
>
{content}
</Markdown>
It renders both the <Gist> and the normal <h1> as <h1. Paragraph tags seem to be automatically added if you add line breaks and something like # Title is also automatically wrapped.
<Gist> in source is converted to lowercase, so it'd only matter for the overrides object (lowercase again). Handles all my custom stuff and html predictably.

Can only set one of `children` or `props.dangerouslySetInnerHTML`

I'm trying to set the inner HTML of an alert div, but receiving the error message : Can only set one of 'children' or props.dangerouslySetInnerHTML'.
Why does this happen ?
function alertContent(alert) { return {__html: alert.text} }
const Alerts = ({ alerts=[{level: 'warning', text:'<p>Warning message!</p>'}], onDismiss }) => (
<div className="alerts">
{alerts.map(alert =>
<Alert
bsStyle={alert.level}
key={alert.id}
onDismiss={onDismiss}
dangerouslySetInnerHTML={alertContent(alert)}
></Alert>
)}
</div>
)
I had this error message in a react application.
My issue was I had code as below
<p dangerouslySetInnerHTML={{ __html:stringContainingHtml}}> </p>
My issue was the space in the <p> </p> tags - since html gets injected inside these tags the space was causing an issue as it wasn't empty.
Hope this might help some people.
This happens because dangerouslySetInnerHTML can only be applied to one element. In your case, <Alert/> is a complex element made up of multiple children. That being said, the BS Alert component does accept HTML:
<Alert bsStyle="warning">
<strong>Holy guacamole!</strong> Best check yo self, you're not looking too good.
</Alert>
or
<Alert bsStyle="warning">
<span dangerouslySetInnerHTML={alertContent(alert)} />
</Alert>
Solution, You have to make a separate component to render element in which you are using dangerously set.....
For Example:
const RenderHTML = (props) => (<span dangerouslySetInnerHTML={{__html:props.HTML}}></span>)
YourData.map((d,i) => {
return <RenderHTML HTML={d.YOUR_HTML} />
})
you have to close the html tag short hand if there aren't inner HTML
<Alert dang...={} />
instead <Alert></Alert>
I have solved this issue myself.
When you are recursively rendering a component, you must separate out the part of the component where dangerouslySetInnerHTML is being used into another component and then use that component in the one you are recursively rendering.

Resources