React problem: Not allowed to load local resource - Images of products - reactjs

I'm trying to create a products list to show some headsets. But I can't show the images of the products.
I have a ProductCard component and a MainContent Component
const ProductCard = [
{
id:1,
productName:"Morcego Preto",
description:"Confortável e com alta qualidade sonora",
price: 399,
currency: "$",
thumb: "/public/assets/1.png",
}...
const MainContent = () => {
console.log(ProductCard);
const listItems = ProductCard.map((item) =>
<div className="card" key={item.id}>
<div className="cardImg">
<img src={item.thumb} alt="Headsets Fallen Store" />
</div>...
But in the browser I receive the "Not allowed to load local resource" message when I try to render it.
Can anyone help me to understand the problem?
Here is the repository: https://github.com/CarlosHenriqueMkt/headset-ecommerce-list

in you data folder inside the js file do it like that
`import yourImage_0 from '../your URL_0'
import yourImage_1 from '../your URL_1'
import yourImage_2 from '../your URL_2'
import yourImage_3 from '../your URL_3'
const myData = [
{
name: 'hello world 0',
image: yourImage_0,
another_thank: 'hi world'
},
{
name: 'hello world 1',
image: yourImage_1,
another_thank: 'hi world'
},
{
name: 'hello world 2',
image: yourImage_2,
another_thank: 'hi world'
},
{
name: 'hello world 3',
image: yourImage_3,
another_thank: 'hi world'
},
]

Error fixed:
I don't need to declared the "public" path. So, the correct path was
./assets/imageName.png

Related

Storybook saving values of properties with the same name

If I am at the docs page and then go to another component that has the same name on the properties it will cause the value of the control input of that property to the keep that same value.
What's even odder is that storybook isnt even using that value, the component is still rendered with the "real" value.
This same bug is causing some controls to just be "set object", "set string" etc.
If I go to the canvas page and back, or if click the "reset controls" button it will restore to default and show objects and strings as they should.
Anyone encountered this and figured out a solution?
I am suspecting it has something to do with using Typescript, and some of the documentations being automatically generated somehow, is it possible to turn this off?
Here is some example code of a story:
import Component from "##/components/Component";
import { Meta, Story } from "#storybook/react";
const meta: Meta = {
title: "Components/Component",
component: Component,
};
export default meta;
const Template: Story = (args) => (
<div style={{ maxWidth: "500px" }}>
<Component
header=""
items={[]}
{...args}
/>
</div>
);
export const Story = Template.bind({});
Story.args = {
header: "Header",
list: [
{
name: "Test 1",
},
{
name: "Test 2",
},
],
};
Story.argTypes = {
list: {
description: "List of items",
table: {
type: {
summary: "Array",
},
},
},
};
I figured it out.
I had several components all under the same title: "XXX/YYY" instead of "XXX/YYY/ComponentName".

Next JS - how to give object a unique id?

I am trying to give my object a unique id by using Math.random, but I am getting the error below. If I change the Math.random to a integer like 4, the error goes away but I need the id to be unique.
Unhandled Runtime Error
Error: Text content does not match server-rendered HTML.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
const data = [
{
id: Math.random(),
sentence: 'hello there',
},
{
id: Math.random(),
sentence: 'bye!',
},
]
export default function Index(props) {
return (
<div>
<h1>{data[0].id}</h1>
<h1>{data[0].sentence}</h1>
<h1>{data[1].id}</h1>
<h1>{data[1].sentence}</h1>
</div>
)
}
As explained in my comment and one of the answers, the problem is happening because Next.js pre-renders pages, therefore, the random number generated by Math.random() when pre-rendering the page on the server doesn't match the random number generated client-side when hydration occurs.
I'm not quite sure what you're trying to achieve by setting random ids to what seems to be "dummy data" (You could do it manually with constant values that will match both server and client-side) but I understand that this might be a simplified example.
You have a couple of options, typically you'd want to move any random generation code/logic inside a useEffect hook so it executes on the client-side only.
Another solution would be to move your "dummy data" and the rendering of this data to a separate component, let's call it DummyComponent:
const data = [
{
id: Math.random(),
sentence: 'hello there',
},
{
id: Math.random(),
sentence: 'bye!',
},
]
const DummyComponent = () => (
<>
<h1>{data[0].id}</h1>
<h1>{data[0].sentence</h1>
<h1>{data[1].id}</h1>
<h1>{data[1].sentence}</h1>
</>
)
export default DummyComponent
And import it dynamically on your page disabling ssr:
import dynamic from 'next/dynamic'
const DummyComponent = dynamic(() => import('../components/DummyComponent'), {
ssr: false,
})
export default function Index(props) {
return (
<div>
<DummyComponent />
</div>
)
}
Use the uuid npm package to generate unique id's.
import { v4 } from "uuid";
const data = [
{
id: v4(),
sentence: 'hello there',
},
{
id: v4(),
sentence: 'bye!',
},
]
First, the page is rendered on the server, then returned to the client to rehydrate, two times initializing data would cause different ID values. This is called hydration mismatch, which is solved by useId in React 18
But using NextJS, you could solve this problem by initializing data on server to keep it consistent
export default function Index(props) {
return (
<div>
<h1>{props.data[0].id}</h1>
<h1>{props.data[0].sentence}</h1>
<h1>{props.data[1].id}</h1>
<h1>{props.data[1].sentence}</h1>
</div>
);
}
export async function getServerSideProps(context) {
return {
props: {
data: [
{
id: Math.random(),
sentence: 'hello there',
},
{
id: Math.random(),
sentence: 'bye!z',
},
],
}, // will be passed to the page component as props
};
}
Stackblitz demo
References
getServerSideProps

using react-draft-wysiwyg converted to html

I am using react WYSIWYG for the first time in a custom email template. i need to draft template messages that will be sent as email body. from WYSIWYG editor, i can achive this. during the extraction of html from draft-js, i am unable to return jsx or html that will be rendered as body when the email is sent. before i send the email itself, i first tried rendering the value extracted from the editor, but istead, it renders stringified html, when i try using draft to markdown, this work but html formatting is lost, which is also what am not looking for. below is my code
import React, { useState } from "react";
import { Editor } from "react-draft-wysiwyg";
import { EditorState, convertToRaw } from "draft-js";
import "../../node_modules/react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import "./editor.css";
import draftToHtml from "draftjs-to-html";
import draftToMarkdown from 'draftjs-to-markdown';
const EditorBook = () => {
const [editorState, setEditorState] = useState(EditorState.createEmpty());
const text = draftToHtml(convertToRaw(editorState.getCurrentContent()))
return (
<div>
<Editor
editorState={editorState}
editorClassName="editor-class"
onEditorStateChange={setEditorState}
placeholder="enter text reminders ..."
mention={{
separator: " ",
trigger: "#",
suggestions: [
{ text: "APPLE", value: "apple", url: "apple" },
{ text: "BANANA", value: "banana", url: "banana" },
{ text: "CHERRY", value: "cherry", url: "cherry" },
{ text: "DURIAN", value: "durian", url: "durian" },
{ text: "EGGFRUIT", value: "eggfruit", url: "eggfruit" },
{ text: "FIG", value: "fig", url: "fig" },
{ text: "GRAPEFRUIT", value: "grapefruit", url: "grapefruit" },
{ text: "HONEYDEW", value: 'honeydew', url: "honeydew" },
],
}}
/>
<button
onClick={() =>
console.log(
draftToHtml(convertToRaw(editorState.getCurrentContent()))
)
}
>
console.log me
</button>
<div>
{text}
</div>
</div>
);
};
export default EditorBook;
when console loged, this is what appears to the console:
<p>here is sample text</p>
now this same text, is what is displayed to the frontend "as a string" yet i just want the text only to be displayed like so:
const text = draftToHtml(convertToRaw(editorState.getCurrentContent()))
when i do this in the react JSX,
<div>
{text}
</div>
i get this in the browser:
here is sample text
when i use the "draftToMarkdown" i get what i want, but formating is lost like this:
const honey = draftToMarkdown(convertToRaw(editorState.getCurrentContent()))
when console logged
<p>this is a sample text</p>
<p>hello every one. (this statement should be on the second line)</p>
result on the browser:
this is a sample text hello every one. (this statement should be on the second line)
I understand the the is an inline block element but i want it in a way that when the keyboard 'Enter' is press, and some text followed, it should appear as a newline in the browser. how can i achieve this ?

Dynamically change Image -> React component

I have an array data which is passed to a reusable component.
const data = [
{
title: "A",
source: "facebook",
},
{
title: "B",
source: "youtube",
},
{
title: "C",
source: "twitter",
},
];
This is how my re-useable component looks like :
import facebook from "../../images/facebook.png";
import youtube from "../../images/youtube.png";
import twitter from "../../images/twitter.png";
function NumberBox({ data }) {
return (
<>
{data.map((item) => (
<>
<div className="title">{item.title}</div>
<img src={item.source} className="image" />
</>
))}
</>
);
}
I want to dynamically change the img element based on the data from props...like facebook icon, Twitter icon etc. With the code I have written here, i get blank image icon against {item.source} all the time but if i replace {item.source} with {facebook} it works properly. Can someone tell me what I'm doing wrong here?
Thanks.
The string "facebook" is not the same as the image facebook, which will be resolved by webpack to be the full url to the image. You can do it in two ways, one using a map:
image_map = {
facebook: facebook,
...
}
<img src={image_map[data.source}]>
Other way is to place the url in data:
import facebook from '../images/facebook.png'
data = [
title: 'facebook',
image: facebook // Notice: no quotes
]
source: twitter Source must be a reference to a variable( you imported img source), not a string
const data = [
{
title: 'A'
source: facebook // facebook but not 'facebook'
},
{
title: 'B'
source: youtube
},
{
title: 'C'
source: twitter
}
];
In your code item.source is a string (like 'facebook'), and has no relation with the image imported import facebook from '../../images/facebook.png';
The easy and clean way is setting the image in data, by importing:
import facebook from '../../images/facebook.png';
const data = [
{
title: 'A',
source: 'facebook',
image: facebook,
},
... or usign a public url:
const data = [
{
title: 'A',
source: 'facebook',
image: 'https://domain/public-url-to-image.jpg',
},
and later:
<img src={data.image} />
item.source is a string not a source path to a file. To resolve this issue you can check which item.source is and use the source from the import statement like following:
function NumberBox({ data }) {
return (
<>
{data.map((item) => (
<>
<div className="title">{item.title}</div>
{item.source === 'facebook' && <img src={facebook} className="image" />}
{item.source === 'twitter' && <img src={twitter} className="image" />}
{item.source === 'youtube' && <img src={youtube} className="image" />}
</>
))}
</>
);
}
You are referencing a string which happens to be "facebook", "youtube" or "twitter" it is not an image file. If you use the imported image which name is "twitter" then it will show the image. You have to update your data array to reference the image variable. Remove the quote marks and it should work. Example how to use with links. Your data should be
const data = [
{
title: "A",
source: facebook,
},
{
title: "B",
source: youtube,
},
{
title: "C",
source: twitter,
},
];
https://codepen.io/shnigi/pen/MWvpMeE

React img src from object

How to exract image source from object for img src ?
I have constant defined like this:
const DUMMY_DATA = [
{
name: "Frozen",
image: "../../assets/categories/Frozen.png",
categories: [],
},
{
name: "Baby Care",
image: "../../assets/categories/BabyCare.png",
categories: [],
},
{
name: "Bakery",
image: "../../assets/categories/Bakery.png",
categories: [],
},
]
I want to map over the array and render a list of each object like the below:
const categories = DUMMY_DATA.map((item) => {
return (
<li key={item.name} className={classes.category}>
<img src={item.image} alt="category" />
<span>{item.name}</span>
</li>
);
});
return (
<nav>
<ul className={classes.navBox}>{categories}</ul>
</nav>
);
unfortunately it doesn't work
I would suggest importing the images instead of using paths.
import image1 from '../path/image-1.png'
import image2 from '../path/image-2.png'
import image3 from '../path/image-3.png'
const DUMMY_DATA = [
{
...
image: image1,
},
{
...
image: image2,
},
{
...
image: image2,
}
]
The reason for this is that when your React application is compiled, the relative paths to access those images will be different.
If you really want to use paths instead of importing, I'd suggest using absolute paths but it's not recommended.
I tried to replicate your code in CodeSandBox and it seems everything is syntactically correct. Problem seems to exist in the image paths within your dummy data.

Resources