How to fire this function for my component (React Native)? - reactjs

I have this piece of code of a component that
class List extends Component {
...
render() {
...
return
<TouchableHighlight onPress={()=>this.props.clearFilter()}>
</TouchableHighlight>
...
}
...
}
The parent:
class Nav extends Component {
...
// render implements renderscene for navigator
renderScene(route, navigator){
...
return (
<List
navigator={navigator}
clearFilter={this.props.clearFilter}
ref={component => this._list = component}/>
);
}
and:
export default class App extends Component {
applyfilter(){
//...
}
constructor(props){
...
this.applyfilter = this.applyfilter.bind(this);
}
clearFilter(){
this.setState(
{
_filter:null,
_filterValue:"",
}, ()=>{this.applyFilter();}
);
_renderScene = ({ route }) => {
return <Nav ref={component => this._nav = component} clearFilter={this.clearFilter.bind(this)}/>;
...
}
So I am passing the clearFilter() function along from App to Nav, and Nav passes it on to List. When List's button is pressed, I want the clearFilter() of App to fire, but for it does not compute as a function for some reason.
I am getting undefined is not a function (evaluating '_this3.applyFilter()') every time the button is pressed.
How to fire clearFilter for App from the button of List?

Just a typo mistake: You're creating the function as applyfilterbut you're invoking it as applyFilter inside your clearFilter function. That's why it's throwing an error that it's undefined.

Assuming that you aren't missing some code here, this.applyfilter seems to be not defined anywhere.

Your code is not clearly formatted. looks like you have declared applyFilter outside the class. define it after constructor inside the class.
Personally I prefer using clearFilter={()=> {this.clearFilter()}} instead of clearFilter={this.clearFilter.bind(this)}
Same for applyFilter.
class Button extends Components {
render(){
return(
<TouchableOpacity
onPress={()=>{ this.props.clearFilter() }}
>
</TouchableOpacity>
);
}
}
class List extends Components {
render(){
return(
<Button
clearFilter={()=>{ this.props.clearFilter() }}
/>
);
}
}
export default class Mainapp extends Components {
constructor(props){
super(props);
this.state = {};
}
clearFilter(){
//// do something
this.applyFilter();
}
applyFilter(){
//// do something
}
render(){
return(
<View>
<List
clearFilter={()=>{ this.clearFilter() }}
/>
</View>
);
}
}

Related

Should I keep a global shared component, or using one per child?

My App:
I am implementing a React Native application where a FlatList is used to display each item fullscreen. Each may contain/display several things, like Text, Images, GIFs. Also, some sound/song may be played. Think of this like a "enhanced" gallery/carousel.
My actual implementation is something like:
export default class App extends React.PureComponent {
this.state = {
currentIndex: null //currentIndex gets updated when displayed FlatList item changes
};
// Black magic here to update currentIndex
render() {
const data = [{image: "...", text: "...", sound: "..."}, {...},...]
return (
<FlatList
data = {data}
renderItem={({ item, index }) => {
const isDisplayed = this.state.currentIndex === index;
return <Thing {...item} isDisplayed={isDisplayed} />;
}}
...
/>
}
}
The Thing component is something similar to:
export default class Thing extends React.PureComponent {
render() {
if (this.props.isDisplayed){
<SoundComponent sound={this.props.sound}/>
<View>
<Text> this.props.text</Text>
<Image> this.props.image</Image>
</View>
}
}
My question:
Should I keep one SoundComponent per Thing, or should I use one global SoundComponent managed by and inside App? On one side I think that App should be unaware of how data is used, on the other side one centralized SoundComponent seems easier to orchestrate one sound at the time.
Notice that only one sound can be played at the same time.
There isn't any kind of "global" component in React. Every component has to be imported or passed as a prop. You have a few options if you want to avoid adding an import to each file though:
1) Create a Higher Order Component that renders the PageContent and the wrapped component.
import PageContent from './PageContent';
const withPageContent = WrappedComponent => {
return class extends React.Component {
render () {
return (
<PageContent>
<WrappedComponent />
</PageContent>
)
}
}
};
export default withPageContent;
// Usage
import withPageContent from './withPageContent';
class MyComponent extends React.Component {
render () {
return (
<div>
I'm wrapped in PageContent!
</div>
)
}
}
export default withPageContent(MyComponent);
2) Pass PageContent as a prop to a component:
import PageContent from './PageContent';
export default class App extends React.Component {
render() {
return (
<React.Fragment>
<Child1 content={PageContent} />
<Child2 content={PageContent} />
</React.Fragment>
)
}
}
// Usage
export default class Child1 extends React.Component {
render () {
const PageContent = this.props.content;
return (
<PageContent>
I'm wrapped in PageContent!
</PageContent>
)
}
}
export default class Child2 extends React.Component {
render () {
const PageContent = this.props.content;
return (
<PageContent>
I'm wrapped in PageContent!
</PageContent>
)
}
}

Calling child method from Parent in Reactjs

I know it's a question asked many times on SO but I am still facing a problem don't know how to resolve.
import Events from './subComponents/Events'
export default class userHome extends Component {
constructor() {
super();
this.state = {
events:[],
};
this.changeView=React.createRef();
}
changeViewClick = () =>{
this.changeView.current.changeDataView();
};
render() {
const {events} = this.state
return (
<IconButton onClick={this.changeViewClick}>
<CardView />
</IconButton >
<IconButton onClick={this.changeViewClick}>
<TableView />
</IconButton>
<Events ref={this.changeView} events={events} />
);
}
}
Events Component
export default class Events extends Component {
constructor(props) {
super(props);
}
changeDataView = () => {
console.log("hi");
}
render() {
return (<div>Hey Child</div>);
}
}
I am getting error as
TypeError: _this.changeView.current.changeDataView is not a function
My reactjs version is 16.6.3
In my opinion, have you tried to pass an anonymous function to child component ?
onClick={() => this.yourfunction()}
It happened, I think, because you called in your child component this props : this.changeView.current.changeDataView()
So when you pass that props in the child component you must passed it as an anonymous function to tell React it's a function to execute when the onClick event is triggered.
Let me know if that resolve your problem or if I am wrong

React Native Show/Hide View

I have a file called test.js. It has two Classes A and B. In class B I have a button hide view.
What I want is when I click on hide view button then it should toggle(show/hide) the view of class A without loading.
How can I do this?
You can use this example:
export default class A extends Component {
constructor(props){
super(props)
this.state = {showComponmentB: true}
}
_toggleShow = () => {
this.setState({showComponmentB: !this.state.showComponmentB})
}
render() {
return (
<View style={styles.container}>
{this.state.showComponmentB && <B/>}
<Button title="toggle button" onPress={this._toggleShow}/>
</View>
);
}
}
export class B extends Component {
render() {
return (
<SomeView/>
);
}
}

Export functions out of react native components

I just want to export a function to an actions.js file but i cannot get to work.
This is the working base:
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
visible: false
}
}
onOpen = () => {
this.setState({visible:true});
console.log(this.state.visible);
}
render() {
return (
<View style={styles.container}>
<Button onPress={()=>{this.onOpen();}}>More</Button>
</View>
);
}
}
And now i tried this, which gives me an error when i press the button:
Error:
Unhandled JS Exception: _this.setState is not a function. (In '_this.setState({ visible: true })', '_this.setState' is undefined)
Code:
let onOpen = () => {
this.setState({visible:true});
console.log(this.state.visible);
}
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
visible: false
}
this.onOpen = onOpen.bind(this);
}
render() {
return (
<View style={styles.container}>
<Button onPress={()=>{this.onOpen();}}>More</Button>
</View>
);
}
}
You cannot use the 'this' keyword outside the class Component. you cannot change the state of the component from outside the class.
More details here:
Change state Outside Component
Further, If you want to change the state of the component outside a class, make use of redux state.
Redux JS
The problem with your code is that you've define onOpen outside your class and you want to access setState function of the Component. I don't know why one would want to do this because onOpen belongs to class. But still if you want to put this outside class. You can do this by following way:
let onOpen = ({setState}) => {
//retrieve setState here
setState({visible:true});
}
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
visible: false
}
// You don't have to do this if onOpen is not in your class
//this.onOpen = onOpen.bind(this);
}
render() {
//send this.setState to onOpen
const that = this;
return (
<View style={styles.container}>
<Button onPress={()=>{onOpen({setState: that.setState});}}>More</Button>
</View>
);
}
}

Calling a React function PropType from outside the class definition

I have the following React Component..
import React, { Component,PropTypes } from 'react';
import RequestListItem from '../RequestListItem';
import { ScrollView,Text,View } from 'react-native';
class RequestList extends Component {
render(){
return (
<ScrollView
onScroll={() => { console.log('onScroll!'); }}
automaticallyAdjustContentInsets={false}
scrollEventThrottle={200}>
{this.props.requests.map(mapRequests)}
</ScrollView>
);
}
}
RequestList.propTypes = {
requests: PropTypes.array.isRequired,
onRequestItemClick: PropTypes.func.isRequired
};
var mapRequests = (request, i) => {
<RequestListItem
id={request.id}
title={request.title}
onRequestItemClick={this.props.onRequestItemClick.bind(this)}
/>
};
export default RequestList;
The problem I am having is concerning the mapRequest function. I need to be able to invoke the onRequestItemClick that is passed in as a property to this component,but since this is defined outside of the class definition, it doesn't appear I have access to the properties. How do I accomplish what the code above is trying to do?
You can pass the callback to the mapRequests method, instead of trying to pull it directly from the props:
class RequestList extends Component {
constructor(props) {
super(props);
this.props.onRequestItemClick = this.props.onRequestItemClick.bind(this) // I'm not sure why your binding to this something you got from the props, so consider removing this line
}
render(){
return (
<ScrollView
onScroll={() => { console.log('onScroll!'); }}
automaticallyAdjustContentInsets={false}
scrollEventThrottle={200}>
{this.props.requests.map((request) => mapRequests(request, this.props.onRequestItemClick))} // the arrow function calls mapRequest, and passes the request and the callback
</ScrollView>
);
}
}
var mapRequests = (request, onRequestItemClick) => {
<RequestListItem
id={request.id}
title={request.title}
onRequestItemClick={onRequestItemClick}
/>
};
However, if you already use an anonymous function, you don't need mapRequests function anyway:
class RequestList extends Component {
constructor(props) {
super(props);
this.props.onRequestItemClick = this.props.onRequestItemClick.bind(this) // I'm not sure why your binding to this something you got from the props, so consider removing this line
}
render(){
return (
<ScrollView
onScroll={() => { console.log('onScroll!'); }}
automaticallyAdjustContentInsets={false}
scrollEventThrottle={200}>
{this.props.requests.map((request) => (
<RequestListItem
id={request.id}
title={request.title}
onRequestItemClick={this.props.onRequestItemClick}
/>
)}
</ScrollView>
);
}
}

Resources