React putting props as variables in javascript template literals - javascript

I'm trying to pass a react props into a javascript template literal:
function Yuh(props) {
return <a href={`javascript:console.log(${props.i})`}>{props.i} <h2>a</h2></a>
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Yuh i='lmao' />);
But I'm getting this error:
Uncaught ReferenceError: lmao is not defined
I tried to replace i='lmao' with i={5} and that seems to work. How do I make it so that strings also work?
Thanks!

lamo is string but 5 is number you need wrap lamo with quote or double quotation :
function Yuh(props) {
return <a href={`javascript:console.log("${props.i}")`}>{props.i} <h2>a</h2></a>
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Yuh i='lmao' />);
if you dont wrap, browser think lamo is a variable , not a string :
i change here :
href={`javascript:console.log("${props.i}")`}

Related

why do we use curly braces while defining constant variable in react js?

i write this following code to fetch the title from props .
Before:
export default function Articleinfo(props) {
const {edge} = props.data.allNodeArticle;
return(
<>
<div>
<h1>Title:{edge[0].title}</h1>
<h2>info:</h2>
</div>
</>
);
};
i getting this error : Cannot read properties of undefined (reading '0')
But After : When i remove the curly braces it worked
export default function Articleinfo(props) {
const edge = props.data.allNodeArticle;
console.log(edge.nodes[0].title);
const Title = edge.nodes[0].title;
return(
<>
<div>
<h1>Title:{edge.nodes[0].title}</h1>
<h2>info:</h2>
</div>
</>
);
};
Can some explain me why this happen? what is the concept behind it?
Curly braces are used for Object destructuring
In the link below syntax for object destructing is explained
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring
So when you do
const {edge} = props.data.allNodeArticle;
this means that the object allNodeArticle has a key named edge and you are accessing it
But when you do the followinng and error goes it means allNodeArticle is not an object having a key edge instead it has array nodes it.
const edge = props.data.allNodeArticle;
console.log(edge.nodes[0].title);

JS React: replacing regex with component in a string

Given a string with the format:
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.'
I'd like to split it using a RegEx and replace the coincidences with some React components. The string would have the type of component (FaIcon) and a props in it such as the name of the icon (Upload).
The objective with this is to be able to use React components within translated strings, and the expected return value would be something like:
[
'This is a string with some ',
<FaIcon iconName="Upload" />,
' in it as ',
<FaIcon iconName="Download" />,
' these two.'
]
The method
Currently, I've got a method which returns either a string or an array. This is compatible with React render methods, since if we return an array it will be capable of rendering any components on that array.
As I'll use it to translate some strings, I've created this custom hook:
const useCustomTranslation = () => {
const { t } = useTranslation();
const tlt = (...args) => {
// const str = t(...args);
const testStr =
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.';
const reg = /(?<=::FaIcon)(.*?)(?=::)/g;
const preStrAr = testStr.split(reg);
console.log(preStrAr);
};
return { tlt };
};
The problem
Currently, this method is logging this:
[
"This is a string with some ::FaIcon",
"Upload",
":: icons in it as ::FaIcon",
"Download",
":: these two."
]
As you can see, it's not including the ::FaIcon and the final ::, as I haven't been able to find the right Regex to do so. But even if I got to that point, I feel like then I should have to re-iterate through the array to replace the strings with the right component, again using Regex to see if the array item matches the right format.
I find this somehow overcomplicated, and I think there has to be a much cleaner and easy way to get it (correct me if maybe I'm wrong and this is the only way).
Is there any way where I can split a string using a Regex, using part of the matched group to replace the string by another content using that matched string?
Perhaps you meant to do this?
/::FaIcon(.*?)::/ without the look
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/::FaIcon(.*?)::/g,function(_,match) {
return `<FaIcon iconName="${match}" />`
})
console.log(newText)
To make an array you can do
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/\s?::FaIcon(.*?)::\s?/g,function(_,match) {
return `::<FaIcon iconName="${match}" />::`
}).split("::")
console.log(newText)
Finally, I've made it using (sadly) the re-iteration method, as it's the only way I can see it would work. Thanks to #mplungjan for his first answer, which gave me the hints to get it working:
export const replaceIconInStr = (str) => {
// Matches the whole icon component pattern
const regComponent = /(::FaIcon.*?::)/g;
// Matches just the component prop we need
const regIconName = /::FaIcon(.*?)::/g;
// Split the string by the component pattern
const splittedStr = str.split(regComponent);
// If there are any matches
if (splittedStr.length) {
// Match the elements in the array and get the prop to replace it by the real component
return splittedStr.map((el) => {
const matched = regIconName.exec(el)?.[1];
if (matched) {
return <FaIcon iconName={matched} />;
}
return el;
});
}
// If there is no pattern matching, return the original string
return str;
};

ReactIntl.FormattedPlural Component to String

I am new to React.
I used ReactIntl.FormattedPlural to format the plural.
<FormattedPlural
value={10}
one='message'
other='messages'
/>
It works when I place this component in the render() function. However, I have a scenario that I want to get the String and passed into a function.
Instead of Using {value ==1 ? 'message' : 'messages'}, can I use ReactIntl.FormattedPlural to achieve this?
In any case, in the end you need to put it into the render.
Because the FormattedPlural is a component. To display it, you need to render it. It's how React works.
You can save it as variable:
const text = (<FormattedPlural value={10} one='message' other='messages' />)
For example if you have a condition and need to decide which string to render.
But in the end, the text should passed to the render to be displayed for user.
Derived from FormattedPlural implementation:
const { formatPlural } = useIntl()
// get the plural category ("one" or "other")
const pluralCategory = formatPlural(count);
const options = {
one: "message",
other: "messages",
}
const plural = options[pluralCategory as 'one'] || options.other;
See also: https://formatjs.io/docs/react-intl/api/#formatplural

Cannot read property 'map' of undefined reactjs when i have declared the property already

Hi I am running the following , I have set textfield property to a string and as far as I know thats an array and map functions should work on arrays but it still says Cannot read property 'map' of undefined, well Is it not defined in there in the state? Thanks
class App extends Component {
state={
textfield:"first value",
}
makeUnique =(textfield)=>{
return String.prototype.concat(...new Set(textfield) );
}
textchanged = (event)=>{
this.setState({
textfield:event.target.value,
caltexlength:event.target.value.length,
})
}
render() {
let uniquechars=null;
uniquechars=(<div>
{
this.textfield.map((char,index)=>{
return <charComponent
char ={this.makeUnique(this.state.textfield)}/>
})
}
</div>)## Heading ##
Write the line this.textfield.map((char,index) as below.
[...this.state.textfield].map((char,index)
With the spread operator you will create an array from your string and you can call map on it.
TextField is a string so why are you doing map on it. Map works only on arrays. To access state TextField it should be this.state.textField but not this.textField
So change
uniquechars=(<div>
{
this.textfield.map((char,index)=>{
return <charComponent
char ={this.makeUnique(this.state.textfield)}/>
})
}
</div>)
To
uniquechars=(<div>
<charComponent
char ={this.makeUnique(this.state.textfield)}/>
</div>)
You have to replace
this.textfield.map
to
this.state.textfield.split('').map

jsx unexpected token passing array of object

<SettingsDropdown labelName="Settings" items={[
{name:'Feature Listing', handler:{this.handle_dropdown_featureListing}, divider:true}
]}/>
What's wrong with my above syntax?
I do have
handle_dropdown_featureListing = () => { //something } but I got unexpected token error still.
handler:{this.handle_dropdown_featureListing}
here you have an object literal that does not have a key.
It must be
handler:{keyName: this.handle_dropdown_featureListing}
or whatever name you need.
Or if you need to pass a single function reference - just remove the curly braces:
handler: this.handle_dropdown_featureListing

Categories

Resources