I have a React Component
export function sendAlert(msg) {
showAlert() //How to call in normal function a function from React.Component
}
export class Alert extends React.Component {
showAlert = () => {
alert("a")
};
render() {
return (
<div>
<h1>Component</h1>
</div>
)
}
}
Its possible to call function which call a function from React.Component
Technically, you can do it, but you should probably extract the common function and call it from both places.
You can do it by creating an instance of the component:
export function sendAlert(msg) {
const alert = new Alert();
alert.showAlert()
}
however, you should extract the code:
function commonShowAlert() {
alert("a");
}
export function sendAlert(msg) {
commonShowAlert();
}
export class Alert extends React.Component {
showAlert = () => {
commonShowAlert();
};
...
...
}
You can do that only if your method is a static one.
You declare your method inside the class as follows :
static showAlert() { alert("a"); }
and then you can access it outside as CLASSNAME.METHOD_NAME
for example : Alert.showAlert();
As #Davin said in his answer, you can declare it outside (that's also my suggestion, cleaner code), but if you have to declare it inside the class, you have the static option.
If your method will not using this, you can use static method
import Alert from '../somewhere';
export function sendAlert(msg) {
Alert.showAlert() // <<--- use Alert.method() to call a static method
}
-
export class Alert extends React.Component {
// Make the method to static
static showAlert = () => {
alert("a")
};
render() {
return (
<div>
<h1>Component</h1>
</div>
)
}
}
Related
I have a function classGenerator which returns a class Klass.
export const classGenerator = () => {
return class Klass extends React.Component {
//....
}
}
How can I now instantiate Klass inside a function somewhere else? I've tried a number of things, such as:
import { classGenerator } from "./class_generator"
function App() {
return(
{/* This syntax here is incorrect */}
<{classGenerator()} />
)
}
But all my attempts have failed, since my syntax is most likely incorrect.
Did you try this?
const Test = classGenerator();
...
<Test/>
I have two components, one is a class component and the other one is a function component.
I want to call method in functionComponentA placed in classComponentA.
I did it by sending the method in props.
I do not want to do it this way
import React, { Component } from 'react'
import functionComponentA from './functionComponentA'
class ClassComponentA extends Component {
constructor(props) {
super(props)
this.state = {
coolVariable : 1
}
functionA= () => {
return "something"
}
render(){
const functionComponentA = <functionComponentA method= {this.doStuff.bind()}/>
return functionComponentA
}
}
export default ClassComponentA
//the code below is in a different file
import ClassComponentA from './ClassComponentA'
function FunctionComponentA (props){
return <input onBlur= {event => {ClassComponentA.functionA()}/>
}
export default FunctionComponentA
when I do as in code above, I get ClassComponentA__WEBPACK_IMPORTED_MODULE_2__.default.functionA is not a function
I do not want to send the function as a props but I want to call it from the file where the other component is placed. Can it be done in any way and what am I doing wrong?
import React, { Component } from 'react'
import functionComponentA from './functionComponentA'
class ClassComponentA extends Component {
constructor(props) {
super(props)
this.state = {
coolVariable : 1
}
functionA= () => {
return "something"
}
render(){
const functionComponentA = <functionComponentA method= {this.doStuff.bind()}/>
return functionComponentA
}
}
export default ClassComponentA
//code below is from a different file
function FunctionComponentA (props){
return <input onBlur= {event => {props.functionA()}/>
}
export default FunctionComponentA
You have many typos and few basic mistakes:
// typo: functionComponentA, no need to bind if you use arrow function
// there is no function doStuff, rename from functionA
<FunctionComponentA method={this.doStuff}/>
// call method() as the prop name and not functionA().
function FunctionComponentA (props){
return <input onBlur={()=> props.method()} />
}
Finally the code should look like so:
class ClassComponentA extends Component {
doStuff = () => {
console.log("hello");
};
render() {
return <FunctionComponentA method={this.doStuff} />;
}
}
function FunctionComponentA(props) {
return <input onBlur={props.method} />;
}
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'm trying to call a parent function with arguments from a child component but I'm not sure exactly how to get it working. I specifically need to be able to call the parent function from the child within another function, so I tried passing a reference to the function through props but this is not quite right. The parent class owns a resource that only it should interact with through the specific function call I'm passing. When done in the following way, I am told the function isn't defined.
export class ParentClass extends React.Component {
ParentFunctionWithArguments(a, b) {
alert("a is being used by my private resource");
alert("b is being used by my private resource");
return true; //some result based on a and b
}
render() {
return (
<ChildClass>ParentFunctionWithArguments={() => this.ParentFunctionWithArguments()}</ChildClass>
);
}
}
And
export class ChildClass extends React.Component {
...
handleOk = (e) => {
...
if (condition) {
if (this.props.ParentFunctionWithArguments(a, b)) {}
}
...
};
...
}
<childComponent callFromChild={this.parentMethod}/>
//in child component call like below
this.props.callFromChild()
You simply need to the apss the parent function as props to the Child component and not call it within the children
export class ParentClass extends React.Component {
ParentFunctionWithArguments(a, b) {
alert("a is being used by my private resource");
alert("b is being used by my private resource");
return true; //some result based on a and b
}
render() {
return (
<ChildClass ParentFunctionWithArguments={this.ParentFunctionWithArguments}></ChildClass>
);
}
}
and simply call it in child like
export class ChildClass extends React.Component {
handleOk = (e) => {
...
if (condition) {
if (this.props.ParentFunctionWithArguments(a, b)) {}
}
...
};
...
}
What I was looking for was the "bind" function
something like this in the constructor of the parent:
export class ParentClass extends React.component {
constructor() {
this.ParentFunctionWithArguments = this.ParentFunctionWithArguments.bind(this);
}
... //rest unchanged
}
This will allow the child to use the passed in parent function in vanilla react.
I am using React v0.14.8. I tried to call the fetchData function from another component. Here is my code:
export default class TagUtils extends React.Component {
deleteTag = () => {
Tags.deleteTag(this.props.tag).then(function(response){
if(response.message === 'tag successfully deleted')
Sidebar.fetchData();
});
}
// other codes
And:
export default class Sidebar extends React.Component {
fetchData() {
Tags.getTags().done((response) => {
this.setState({tags: response.tags || [], loaded: true});
});
}
//other codes
When I called deleteTag, I got this error in my console:
TypeError: _SidebarJsx2.default.fetchData is not a function
You can't call Sidebar.fetchData because fetchData is not a static member of Sidebar, it is an instance member. This means you need an instance of Sidebar to call fetchData on, for example new Sidebar().fetchData(). Of course, this is not how a React component is supposed to be used, and it would not set state on all other Sidebar instances, so it wouldn't be meaningful.
What you want to do is pass a callback to your TagUtils component:
export default class TagUtils extends React.Component {
deleteTag = () => {
Tags.deleteTag(this.props.tag).then((response) => {
if(response.message === 'tag successfully deleted')
this.props.onDeleteTag();
});
}
}
export default class Sidebar extends React.Component {
fetchData() {
Tags.getTags().done((response) => {
this.setState({tags: response.tags || [], loaded: true});
});
}
render() {
return (
{ this.state.tags.map((tag) =>
<TagUtils tag={tag} onDeleteTag={this.fetchData} />) }
);
}
}
If you have to thread this callback through several layers of components that's okay, that's typical in React. However, if you find yourself passing a lot of stuff down props through many component layers that seem out of place, or trying to reconcile changes across large horizontal spaces in your app, this is a primary use-case for things like Flux and Redux.