React.Intl substring from <FormattedMessage> - javascript

I'm working on my first project with i18n and I've run into this issue. My client wants a navigation bar with texts expanding depending on the currently viewed section. Something like this:
So for each label I'm using FormattedMessages like this:
<FormattedMessage id="navigation.what"/>
<FormattedMessage id="navigation.how"/>
I get all the strings from .json file.
Now I'm thinking - do you know if there's any way to use .substring on the FormattedMessage?
Also does this approach make any sense or should I just use different strings for expanded and shortened label in .json and be done with it?

<FormattedMessage id="navigation.what"/> component will always returns a span. For getting string from react-intl, you should be using formatMessage() function. You can use it like the below:
Inject Intl using injectIntl higher order component:
import { injectIntl } from 'react-intl';
#injectIntl
class YourComponent extends Component {
...
render () {
...
const {formatMessage} = this.props.intl;
...
<span>{formatMessage(navigation.how).substring()}</span>
Go through this function for more details:
formatMessage()
Usage example

Related

reactjs in VSCode: how to find out all scripts that imported component from current script?

I'm new to using VSCode and the programming language reactjs, so excuse me if this is obvious. I'm troubled with the following situation:
In many reactjs projects, the component defined in a .js file is imported in another script under a different name.
Sometimes, the component defined in a .js file are not even exported with a name. E.g. export default {...} or export default (...) => {... some code ...}
How do I find all the occurrences of the component throughout the project in these situations?
What I need is a method or tool that can locate all places where the component is imported/used, since doing a "global search" on the name with "Match Case" and "Match Whole Word" is not useful at all in these situations. 1. It is imported under a different name, so knowing the export name is not useful; 2. It has no name to start the search.
Its the feature of the library react.js that you can export a component by its name or by using the keyword 'default';
1): If you export a component by the keyword 'default' with the name of the component besides default than you can use it in any other script by importing any name e.g export default AppBar than import App from './AppBar'
2): If you just export the component by not giving it the name than it will be an anonymously exported function which you can named anything while importing it in any other script
To expand on what Saima Ashraf already said:
Naming Components
When you create a React Component, I would highly recommend to give it a name, best practice it is the same name as the file name, for example:
Navbar.js
export default Navbar() {
return (
<ul>
<li>Home</li>
<li>About</li>
</ul>
)
}
And in another file you import it with the name you have given it.
// Layout.js
import Navbar from "./Navbar";
export default Layout() {
return <Navbar />
}
When creating new Components, they always should have a descriptive name of what they do.
How to find the components
VS Code
In VS Code on the left sidebar, you have a search function. It is the Magnifying glass Icon. You can write the name of your component and activate the settings "Match Case" and "Match Whole Word". SO if you were to search for "Navbar" you would get all the files that have Navbar used as a word in the file, which is usually the component being used.
React Dev Tools
You can also install the React Dev Tool extension on your browser with which you can check out the component tree being used. It also has a search function, so you can search for a specific component like "Navbar".

How to live edit a class/functional component on Storybook

Hello i m using storybook/react library to create stories of my components.
So far so good, I followed the tutorial on https://www.learnstorybook.com/react/en/get-started and i have add stories on the left side of the screen with the add command, like so:
add('archived', () => <Task task={{ ...task, state: 'TASK_ARCHIVED' }} {...actions} /> );
The Task component is a functional component.
I 'm also using the storybook-addon-react-live-edit storybook addon, from https://github.com/vertexbz/storybook-addon-react-live-edit for having live edit on the stories, like so:
The code for the above example is this:
``
stories.addDecorator(withLiveEditScope({ React, Test }));
stories.add('simple JSX', withLiveEdit(return <div>hello there!!</div>, {color: 'red'}))`
This code is simple because i just show jsx code.
Problem
I want to live edit a functional or class component, from another file but the functions withLiveEdit(source[, scope]) and addLiveSource(name, source[, scope]), accept only string as the source.
So if i add the story like so: stories.addLiveSource('demo', return ${Test});
Test is a separate Test.js file:
const Test = class Welcome extends React.Component {
render() {
return <h1>Hello, world!!</h1>;
}
}
export default Test;
Results is, it shows the code on 'live tab', but its not actually rendered on the top window.
So my question is, how can i import class or functional components on addLiveSource()/withLiveEdit()
Thanks.
I hit the same issue, you can do this:
storiesOf(group, module)
.addDecorator(withLiveEditScope({ React, SomeFunctionComponent, StyledHeader }))
.addLiveSource("title", `<SomeFunctionComponent><StyledHeader>hello</StyledHeader></SomeFunctionComponent>`);
Basically anything you use inside the template literal in addLiveSource which would need an import you need to add to withLiveEditScope.
The only drawback is you have to write it all inside the template literal (P.S. if you solve that limitation please let me know!)

How to inject JavaScript in React Native?

I am developing a react native app. I am super confused that how to inject javascript code in react native. Though I am struggling somehow to work with react native but the thing is sometimes I need to inject some javascript code in my react native or say the homescreen.js type files, but I somehow end up into a syntax error. For example:
I am trying to implement this in a stylesheet.
const styles = Stylesheet.create({
//some styles
viewStyle:{
Platform.select({
ios:{
marginTop:2,
},
android:{
marginTop:3
}
});
}
//some styles
});
But it just does not work! it doesn't work even when I apply ...Platform instead of Platform.
**Note: I have import {Platform} from 'react-native'
My version is 0.57.something, but what I want to know is what is the syntax to implement javascript in these files. Just like for example in PHP we have the following:
<?php
//your logic
for(something){
?>
<View></View>
<?php
}
?>
Similarly for other languages we have something like the <% %>, {{ }} tags but what should I use in React Native. I always end up with a syntax error.
So my questions are, can anyone help me understand what the restriction is within React Native and where I can use and should not use tags? And if tags are available what are they?
I am super confused and was unable to find a similar question like this anywhere on Stack Overflow. I'd appreciate anyone's inputs, the more answers the more it will be helpful.
So I'm not sure what kind of structure you have set up but I'm going to assume you have a single file (lets call it homescreen.js) and you want to define styles for a component. I'm assuming you have already imported everything that's necessary (StyleSheet, Platform, View and Text from react-native, and the default export React from react).
So first, let's make the stylesheet. You almost have it correct above, you need the following:
const styles = Stylesheet.create({
viewStyle: Platform.select({
ios:{
marginTop:2,
},
android:{
marginTop:3
}
})
})
(You mention above that you're getting a syntax error, this is probably due to the semicolon in your stylesheet object.)
Now we need to create the React class for your HomeScreen component. Again, not sure of the context but you should be able to pull out the bits you need.
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.viewStyle}>
<Text>I should have marginTop 2 on iOS and marginTop 3 on Android.</Text>
</View>
);
}
}

Next.js: How to dynamically import external client-side only React components into Server-Side-Rendering apps developed?

I know this question has been asked multiple times before but none of the solution seems to work.
I'm trying to use the library 'react-chat-popup' which only renders on client side in a SSR app.(built using next.js framework) The normal way to use this library is to call import {Chat} from 'react-chat-popup' and then render it directly as <Chat/>.
The solution I have found for SSR apps is to check if typedef of window !=== 'undefined' in the componentDidMount method before dynamically importing the library as importing the library normally alone would already cause the window is not defined error. So I found the link https://github.com/zeit/next.js/issues/2940 which suggested the following:
Chat = dynamic(import('react-chat-popup').then(m => {
const {Foo} = m;
Foo.__webpackChunkName = m.__webpackChunkName;
return Foo;
}));
However, my foo object becomes null when I do this. When I print out the m object in the callback, i get {"__webpackChunkName":"react_chat_popup_6445a148970fe64a2d707d15c41abb03"} How do I properly import the library and start using the <Chat/> element in this case?
Next js now has its own way of doing dynamic imports with no SSR.
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)
Here is the link of their docs: next js
I've managed to resolve this by first declaring a variable at the top:
let Chat = ''
then doing the import this way in componentDidMount:
async componentDidMount(){
let result = await import('react-chat-popup')
Chat = result.Chat
this.setState({
appIsMounted: true
})
}
and finally render it like this:
<NoSSR>
{this.state.appIsMounted? <Chat/> : null}
</NoSSR>
You may not always want to include a module on server-side. For
example, when the module includes a library that only works in the
browser.
Import the library normally in child component and import that component dynamically on parent component.
https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
This approach worked for me.

react JS how to make theme-able component

I am trying to decide the best route to go for distributing a component that others can theme. They may need to change the html structure as well as the css/bootstrap styling. (I am using react-bootstrap with the component.
The only way I can see to do this is to make a component folder with all of the subcomponents in src/themes/default, src/themes/awesome, etc and then import them into the main component which people can then call by doing something like this...
This is just a concept, it probably isn't completely valid
import default from './themes/default/index.js`
import awesome from './themes/awesome/index.js`
const themes = {
default,
aweosme,
}
const MyComponent = ({ theme, otherprop }) => {
return (
<themes.default otherprop={otherprop} />
)
}
then if someone wanted to contribute a theme, they would have to write a whole component complete with html structure in the jsx and inline styles to go along with it. It would require them to be familiar with react, but I cannot see another way to do it unless I have missed something...
What do you think?

Categories