I'm separating my code by writing a function in another .js file.
The problem is that I don't have the access to my redux connect function since I'm not using a class in my new .js file.
To clear things up:
This is the function (barChange) inside my class which I want to move in another js file
#connect((store) => {
return {
bar_change:store.bar_change
};
})
export default class Bardoctor extends React.Component {
constructor(props) {
super(props);
}
barChange(arg0){
//function code...
this.props.dispatch(user.changeBarNum(arg0,"bar_change_doctor"));
this.props.dispatch(user.sendBarDataDoctor("doctor_bar_send",temp_arr, flag_it, arg0));
}
In order to use my user. functions I have to have the this.props.dispatch.
How would I use this.props.dispatch if I pack the barChange function in another .js file and export the function and call it in my class?
For example:
import * as user from "../actions/asyncCAll.js"
export function barChange(arg0, prop_arr, prop_next, string_change, string_send){
//function code...
dispatch(user.changeBarNum(arg0,string_change));
dispatch(user.sendBarDataPatient(string_send, temp_arr, flag_it, arg0));
}
You can import store to your new js file and use dispatch method of the store directly.
import store from 'path/to/your/store/file'
function barChange(arg0) {
//function code...
store.dispatch(user.changeBarNum(arg0, "bar_change_doctor"));
store.dispatch(
user.sendBarDataDoctor("doctor_bar_send", temp_arr, flag_it, arg0)
);
}
If you're not creating your store in a separate file using createStore method, I recommend you to do that as follows.
const store = createStore(reducers, //...);
export default store;
Warning: This approach might have complications if you use it with server-side rendering.
Related
for example i want to add a function to return or do something like this:
export const useExample = (name) => {
const script = "hi" + " " + name;
return script
};
and i want to use it in class component so should be this:
import React from 'React'
import {useExample} from "components/utils/useExample"
class App extends React.Component {
componentDidMount(){
const hiMsg = useExample('John')
console.log(hiMsg)
}
render(){
return(
<>
<div>THIS IS AN EXAMPLE</div>
</>
)
}
}
This will give an error like this:
I know that we cannot use hooks in class components, so what is the **fix **of this issue to make the use Example works?
I just want to know how I can import external files like functions who accept parameters and do something with it, and to use this file multiple times in React class component
Just don't have use at the beginning of your function name, so it doesn't think it's a hook function.
Something like getGreeting instead of useExample.
You can export only functions declared with the keyword function that way. If you use const export the functions at the bottom of your file like this:
export {useExample}
or if you have more methods in the same file, than:
export {useExample, someMoreFunctions}
I have multiple components which all need to do the same thing. (A simple function which maps over their child components and does something to each one). At the moment I am defining this method in each of the components. But I only want to define it once.
I could define it in the top level component and then pass it down as a prop. But that doesn't feel quite right. It is more a library function than a prop. (It seems to me).
What is the correct way of doing this?
Utils.js with latest Javascript ES6 syntax
Create the Utils.js file like this with multiple functions, etc
const someCommonValues = ['common', 'values'];
export const doSomethingWithInput = (theInput) => {
//Do something with the input
return theInput;
};
export const justAnAlert = () => {
alert('hello');
};
Then in your components that you want to use the util functions, import the specific functions that are needed. You don't have to import everything
import {doSomethingWithInput, justAnAlert} from './path/to/Utils.js'
And then use these functions within the component like this:
justAnAlert();
<p>{doSomethingWithInput('hello')}</p>
If you use something like browserify then you can have an external file i.e util.js that exports some utility functions.
var doSomething = function(num) {
return num + 1;
}
exports.doSomething = doSomething;
Then require it as needed
var doSomething = require('./util.js').doSomething;
If you want to manipulate state in helper functions follow this:
Create a Helpers.js file:
export function myFunc(){ return this.state.name; //define it according to your needs }
Import helper function in your component file:
import {myFunc} from 'path-to/Helpers.js'
In your constructor add that helper function to the class
constructor(){ super() this.myFunc = myFunc.bind(this) }
In your render function use it:
`render(){
{this.myFunc()}
}`
Here are some examples on how you can reuse a function (FetchUtil.handleError) in a React component (App).
Solution 1: Using CommonJS module syntax
module.exports = {
handleError: function(response) {
if (!response.ok) throw new Error(response.statusText);
return response;
},
};
Solution 2: Using "createClass" (React v16)
util/FetchUtil.js
const createReactClass = require('create-react-class');
const FetchUtil = createReactClass({
statics: {
handleError: function(response) {
if (!response.ok) throw new Error(response.statusText);
return response;
},
},
render() {
},
});
export default FetchUtil;
Note: If you are using React v15.4 (or below) you need to import createClass as follows:
import React from 'react';
const FetchUtil = React.createClass({});
Source: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass
Component (which reuses FetchUtil)
components/App.jsx
import Categories from './Categories.jsx';
import FetchUtil from '../utils/FetchUtil';
import Grid from 'material-ui/Grid';
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {categories: []};
}
componentWillMount() {
window
.fetch('/rest/service/v1/categories')
.then(FetchUtil.handleError)
.then(response => response.json())
.then(categories => this.setState({...this.state, categories}));
}
render() {
return (
<Grid container={true} spacing={16}>
<Grid item={true} xs={12}>
<Categories categories={this.state.categories} />
</Grid>
</Grid>
);
}
}
export default App;
I'll show two styles below, and you'll want to choose depending on how much the components' logic relate to each other.
Style 1 - Relatively related components can be created with callback references, like this, in ./components/App.js...
<SomeItem
ref={(instance) => {this.childA = instance}}
/>
<SomeOtherItem
ref={(instance) => {this.childB = instance}}
/>
And then you can use shared functions between them like this...
this.childA.investigateComponent(this.childB); // call childA function with childB as arg
this.childB.makeNotesOnComponent(this.childA); // call childB function with childA as arg
Style 2 - Util-type components can be created like this, in ./utils/time.js...
export const getTimeDifference = function (start, end) {
// return difference between start and end
}
And then they can be used like this, in ./components/App.js...
import React from 'react';
import {getTimeDifference} from './utils/time.js';
export default class App extends React.Component {
someFunction() {
console.log(getTimeDifference("19:00:00", "20:00:00"));
}
}
Which to use?
If the logic is relatively-related (they only get used together in the same app), then you should share states between components. But if your logic is distantly-related (i.e., math util, text-formatting util), then you should make and import util class functions.
Another solid option other than creating a util file would be to use a higher order component to create a withComponentMapper() wrapper. This component would take in a component as a parameter and return it back with the componentMapper() function passed down as a prop.
This is considered a good practice in React. You can find out how to do so in detail here.
Sounds like a utility function, in that case why not put it in a separate static utility module?
Otherwise if using a transpiler like Babel you can make use of es7's static methods:
class MyComponent extends React.Component {
static someMethod() { ...
Or else if you are using React.createClass you can use the statics object:
var MyComponent = React.createClass({
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
}
However I don't advise those options, it doesn't make sense to include a component for a utility method.
Also you shouldn't be passing a method down through all your components as a prop it will tightly couple them and make refactoring more painful. I advise a plain old utility module.
The other option is to use a mixin to extend the class, but I don't recommend that as you can't do it in es6+ (and I don't see the benefit in this case).
Shouldn't you use a Mixin for this ? See https://facebook.github.io/react/docs/reusable-components.html
Although they are falling out of favour see https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
Might be useful
How can i call a component function from function declared on the outside? Here is the code
function testFunction(){
test();
}
class ChatManager extends Component{
test(){
console.log("Test");
}
render(){
return(
<div className="divChatManager" onClick={()=>testFunction()}>
</div>
)
}
}
How can i call a component function from function declared on the outside? Here is the code
function testFunction(){
test();
}
class ChatManager extends Component{
test(){
console.log("Test");
}
render(){
return(
<div className="divChatManager" onClick={()=>testFunction()}>
</div>
)
}
}
EDITED2
Here is what i am trying to achieve, but couldn't get it working because pushToDetail was inside the ChatManager.js
Error: Attempted import error: 'pushToDetail' is not exported from './components/ChatManager'.
Api.js
import openSocket from 'socket.io-client';
import axios from 'axios';
import { store } from './components/Store'
import { pushToDetail } from './components/ChatManager'
const socket = openSocket("http://localhost:3000/",
{'forceNew': true,
'reconnection': true,
'reconnectionDelay': 1000,
'reconnectionDelayMax': 5000,
'reconnectionAttempts': 999999,
});
function connectToChatRoom(receiver_id){
socket.on(receiver_id, (from_id, message)=>{
console.log(receiver_id + " has received " + message + " from " + from_id);
pushToDetail(message) // I want to send the message from here to ChatManager.js
});
}
ChatManager.js
import ChatManagerStyle from '../styles/ChatManagerStyle.scss';
import axios from 'axios';
import { store } from './Store'
import ChatItem from './ChatItem';
import ChatDetailItem from './ChatDetailItem';
import { connectToChatRoom, disconnectFromChatRoom, socket } from '../Api';
class ChatManager extends Component{
state = {
chatItem: [],
chatDetail: [],
}
constructor(props){
super(props);
};
pushToDetail = (message) => {
this.setState({ chatDetail:[...this.state.chatDetail, message] });
}
}
export { ChatManager, pushToDetail };
There are at least two ways that I can think of to reach your expected behavior, neither of which I recommend. First one by adding test as a static method to the class itself:
function testFunction(){
ChatManager.test(); // Chatmanager itself is an object
}
class ChatManager extends Component{
static test(){ // set test as static function
console.log("Test");
}
}
Second method by using the bind() method to attribute test() function to an instance:
function testFunction(){
this.test(); // call test function on an instance
}
class ChatManager extends Component{
test(){
console.log("Test");
}
render(){
return(
<div className="divChatManager" onClick={ testFunction.bind(this) }>
</div>
)
}
}
Both solutions are very hacky, and as others have mentioned before, the major question you should be asking yourself is why do you want to do this in the first place? Chances are, there is an issue that can be fixed within the conventions of React and not using hacky javascript.
This seems like you're trying to combine 2 concepts. A Component is your view logic. If you need to call a component's method, mark it static but you shouldn't really be mixing view logic with external business logic. That's what utility folders/files are for or even a reducer/middleware pair.
I think what you really want is to define a helper function or factory in a utility file that takes whatever arguments you need to take to produce your output.
If I'm not wrong, eventually your are trying to setState with message. trigger an action to update state using reducer function.
I have a situation to convert several jQuery components to VueJs.
In general, I know what to do, but in some cases, I need to replace some functions calls.
For instance:
Component
const Component = (function () {
const initialize = () => {
return 'Tony Stark'
}
return {
initialize: initialize
}
})
export default Component
Random file, using exported function
$( document ).ready(function() {
Component.initialize()
});
What is the best solution to Component.initialize() still working?
Because I have this request in several files.
I got a solution:
import Component from './component'
// Call method
Component.methods.method()
You may import the component to every Vue component and use it like this:
import someComponent from './someComponent'
export default {
created () {
Component.initialize()
}
}
Or you could use instance properties, see https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html
I'm using React, and I have something like this in my code:
renderDetails.js:
export default renderDetails = (details) => {
// function logic removed for brevity
}
Then, in the same folder, I have another source file from where I want to import it, and I do something like this:
businessDetails.js:
import renderDetails from './renderDetails';
// rest removed for brevity
But, I get an error message pointing to my renderDetails.js file and says: "rederDetails is not defined". Any ideas what the problem might be and how to fix it?
The problem is that even though you are exporting the component as default you are giving it a name which is not defined
You can either do
export default (details) => {
}
or
const renderDetails = (details) => {
}
export default renderDetails;
One more thing, when you are trying to render components, make sure that their name starts with a Uppercase character.
try that way.
functions.jsx
export function renderDetails(details) => {
// function logic removed for brevity
}
then import like,
import { renderDetails } from './functions';
P.S.
./ is for if both files a re in same namespace/folder.
You can also write them like this:
export const exampleFunctionOne = () => {}
export const exampleFunctionTwo = () => {}
Then import the individual functions you require from said file like this:
import { exampleFunctionOne, exampleFunctionTwo } from './exampleFile';
I like this approach when wanting to combine similar functions into one file such as validators or filters making them easy to import and use across your application.