How do I navigate between List and Item? - javascript

I am trying to open an item from my list but my item code is in another js. When I try to use onPress method there is no action. Also I am using Swipeout.
Here is my JobList.js where I am rendering the list of my items.
class JobList extends Component {
onJobDetails = (job) => {
this.props.navigate('JobDetails', job);
}
render() {
const { navigation } = this.props;
var renderJobs = () => {
return this.props.jobs.map((job) => {
return (
<JobItem
key={job._id}
title={job.title}
shortDescription={job.shortDescription}
logo={job.avatar}
company={job.company}
id={job._id}
dispatch={this.props.dispatch}
onPress={() => this.onJobDetails(job)}
/>
)
})
}
return (
<View style={styles.container}>
<ScrollView>
{renderJobs()}
</ScrollView>
</View>
);
}
};
And here is my JobItem.js
class JobItem extends Component {
render() {
return (
<Swipeout {...swipeSettings}>
<View style={styles.jobContainer}>
<View>
<Text style={styles.postTitle}>{this.props.title}</Text>
<Text style={styles.postShortDescription}>{this.props.shortDescription}</Text>
</View>
<View>
<Image
style={styles.postLogo}
source={{uri: '' + this.props.logo + ''}}/>
</View>
</View>
</Swipeout>
)
}
};
Any idea how shall I fix this?

You need to pass onPress prop to the child component in order for it to work.
<Swipeout {...swipeSettings}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
//... other children here
</TouchableWithoutFeedback>
</Swipeout>

Related

Change useState's from remote component

I know with the following code below changing a useState within another component's onPress event wouldn't be possible but how would I do it? I want to make it so when the onPress function within Card.js is executed the popUpData from within App.js is changed.
App.js
const [popUpData, setPopUpData] = React.useState("Nothing")
return (
<Card>
<Text style={styles.pokemonName}>{item.name}</Text>
</Card>
<Text>{popUpData}</Text>
)
Card.js
const doSomething = () => {
setPopUpData("Something")
//other things...
}
return (
<TouchableOpacity activeOpacity={1} style={styles.card} onPress={doSomething()}>
<View style={styles.cardContent}>
{ props.children }
</View>
</TouchableOpacity>
)
App.js
const [popUpData, setPopUpData] = React.useState("Nothing")
return (
<Card onUpdate={(d)=>setPopUpData(d) }>
<Text style={styles.pokemonName}>{item.name}</Text>
</Card>
<Text>{popUpData}</Text>
)
Card.js
function Card(props){
const doSomething = () => {
props.onUpdate("Something")
}
return (
<TouchableOpacity activeOpacity={1} style={styles.card} onPress={doSomething()}>
<View style={styles.cardContent}>
{ props.children }
</View>
</TouchableOpacity>
)
}
Just pass reference to setState function down to child component.
(in the simplest scenario)
const Parent = () => {
const [popUpData, setPopUpData] = React.useState("Nothing")
return (
<Card setPopUpDataHandler={setPopUpData}>
<Text style={styles.pokemonName}>{item.name}</Text>
</Card>
<Text>{popUpData}</Text>
)
}
const Card = ({setPopUpDataHandler, children}) => {
const doSomething = () => {
setPopUpDataHandler("Something")
//other things...
}
return (
<TouchableOpacity activeOpacity={1} style={styles.card} onPress={doSomething()}>
<View style={styles.cardContent}>
{ children }
</View>
</TouchableOpacity>
)
}

Changing style of specific component returned from map function onClick

I am trying to change the style of individual TouchableOpacity components that have been returned from a map function.
Here is the component:
Example = ({ props }) => {
return (
<View>
{props.listExample.map(({ id }) => {
return (
<React.Fragment key={id}>
<TouchableOpacity
style={styles.button}
onPress={() => console.log(id)}>
<Image source={require('example.jpg')} />
</TouchableOpacity>
</React.Fragment>
);
})}
</View>
);
};
Let TouchableOpacity = TO.
The map function returns about 30 TOs with unique IDs. When I click the TOs, I can see their unique ID in the console log. I want to know how I can modify the style of an individual TO.
Here is my render function which uses the functional component Example.
render() {
return (
<View style={styles.body}>
<ScrollView>
<View style={styles.column}>
<this.Example props={{ listExample: this.getList() }} />
</View>
</ScrollView>
</View>
);
}
What I have tried:
referencing this stackoverflow post, I tried to create a function which changed the style of the TO when it is clicked. But the result of this changed all the TOs in the UI since of the way it is mapped.
I tried something like the following.
Example = ({ props }) => {
return (
<View>
{props.listExample.map(({ id }) => {
let buttonStyle = this.state.pressed ? styles.button : styles.buttonClicked
return (
<React.Fragment key={id}>
<TouchableOpacity
style={buttonStyle}
onPress={() => console.log(id)}>
<Image source={require('example.jpg')} />
</TouchableOpacity>
</React.Fragment>
);
})}
</View>
);
};
But as previously stated, this changed all of the Touchable Opacitys. Is there a way to only change one?
Thanks
Edit - to show entire class
class Page extends Component {
constructor(props) {
super(props)
}
MyButton = ({ onButtonPressed = () => {} }) => {
const [isPressed, setIsPressed] = useState(false);
const onPressed = () => {
setIsPressed(!isPressed);
onButtonPressed();
}
return (<TouchableOpacity style={isPressed ? styles.pressedButton: styles.button}
onPress={onPressed}>
<Image source={require('example.jpg')} />
</TouchableOpacity>
);
}
Example = ({ props }) => {
return (
<View>
{props.listExample.map(({ id }) => {
return (
<MyButton key={id}/>
);
})}
</View>
);
};
render() {
return (
<View style={styles.body}>
<ScrollView>
<View style={styles.column}>
<this.Example props={{ listExample: this.getList()}} />
</View>
</ScrollView>
</View>
);
}
}
It is easier to separate the component inside map to a separate component and then handle style changes on press there
const MyButton = ({ onButtonPressed = () => {} }) => {
const [isPressed, setIsPressed] = useState(false);
const onPressed = () => {
setIsPressed(!isPressed);
onButtonPressed();
}
return (<TouchableOpacity style={isPressed ? styles.pressedButton: styles.button}
onPress={onPressed}>
<Image source={require('example.jpg')} />
</TouchableOpacity>
)
}
so you can use in the map like this
Example = ({ props }) => {
return (
<View>
{props.listExample.map(({ id }) => {
return (
<MyButton key={id} />
);
})}
</View>
);
};

How refresh the ListView Component in react native?

I'm trying to create a todo list, then I'm trying to use this checkbox package
react-native-check-box
I don't know if this issue come from that package
when I click the checkbox and click the delete button this is what happen
And here is my code for displaying the list
interface TodoProps{
todo: TodoModel;
ter:string;
}
interface TodoState{
dataSource: any;
myTodo: Array<ITodo>;
}
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => true});
export default class Todo extends React.Component <TodoProps,TodoState>{
constructor(props:TodoProps) {
super(props);
this.state = {
dataSource: ds.cloneWithRows([]), // or put your initial data here
myTodo: []
};
}
componentWillReceiveProps = (nextProps) => {
console.log(this.state.myTodo);
let data = {
title: nextProps.ter,
isChecked: false
};
let todoList = this.state.myTodo;
if (nextProps.ter) {
todoList.push(data);
}
this.setState({
myTodo: todoList
});
}
onDelete(){
let todos = this.state.myTodo.filter((todo:ITodo) => {
return !todo.isChecked;
});
this.setState({
myTodo: todos
});
}
render() {
let dataSource = this.state.dataSource.cloneWithRows(this.state.myTodo);
return (
<View style={styles.container}>
<View style={styles.box2}>
<ListView enableEmptySections={true} dataSource={dataSource} renderRow={(rowData, sectionID, rowID) => <TodoList data={rowData} onClick={this.onClick.bind(this)} id={rowID} /> } />
</View>
<View style={styles.box3}>
<TouchableOpacity style={styles.bbox1} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>All</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox2} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>Complete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox3} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>InComplete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox4} onPress={()=> this.onDestroy()}>
<Text style={styles.tabText}>Delete</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
But if I console log the data. I find all isChecke: to false. Only the view of checkbox is not working. Do I need to use componentwillamount() for this?
Use the below sample code
_onRefresh() {
this.setState({refreshing: true});
// your callback function or call this.componentDidMount()
}
render() {
return (
<ListView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
...
>
...
</ListView>
);
}

How to switch tabs from another component using react-native-scrollable-tab-view

Second day using React Native so I've no idea what I'm doing, but how do I switch tabs from within another component with react-native-scrollable-tab-view?
https://github.com/skv-headless/react-native-scrollable-tab-view
I have a MenuButton in a ButtonPage that I'm trying to switch tabs with using an onPress. However when I tap it I get:
undefined is not an object (evaluating 'this.props.tabView.goToPage')
What I've got is this
export default class Home extends Component {
render() {
return (
<View style={{flex: 1}}>
<StatusBar
barStyle='light-content'/>
<ScrollableTabView initialPage={1} renderTabBar={false}
ref={(tabView) => { this.tabView = tabView}}>
<FriendsPage tabView={this.tabView} tabLabel="Friends" />
<ButtonPage tabView={this.tabView} tabLabel="Button" />
<HangoutsPage tabView={this.tabView} tabLabel="Hangouts" />
</ScrollableTabView>
</View>
)
}
}
And in my ButtonPage I have this
export default class ButtonPage extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.buttonsContainer}>
<HangoutsButton/>
<View style={styles.spacer}/>
<MenuButton/>
</View>
</View>)
}
}
And that MenuButton is described by this
export default class MenuButton extends Component {
constructor(props) {
super(props)
this.goToPage = this.goToPage.bind(this)
}
goToPage(pageNumber) {
this.props.tabView.goToPage(pageNumber)
}
render() {
return (
<Indicator
position='left top'
value='3'
type='warning'>
<TouchableHighlight
onPress={() => this.goToPage(0)}
underlayColor='#ed8600'
style={styles.touchable}>
<Image source={require('./resources/menuicon.png')} style={styles.image} />
</TouchableHighlight>
</Indicator>
)
}
}
How do I get the reference for my scrollableTabView all the way down to my button so I can tap it and change the page with goToPage?
I assumed you could stick the object in a prop and pass that prop all the way down and then use the function goToPage on it from MenuButton.
You don't need to tabview ref all the way down. Just use
export default class MenuButton extends Component {
render() {
return (
<Indicator
position='left top'
value='3'
type='warning'>
<TouchableHighlight
onPress={() => this.props.onPress && this.props.onPress()}
underlayColor='#ed8600'
style={styles.touchable}>
<Image source={require('./resources/menuicon.png')} style={styles.image} />
</TouchableHighlight>
</Indicator>
)
}}
export default class ButtonPage extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.buttonsContainer}>
<HangoutsButton/>
<View style={styles.spacer}/>
<MenuButton onPress={ () => this.props.goToPage && this.props.goToPage() }/>
</View>
</View>)
}}
And finally
export default class Home extends Component {
goToPage(pageId) {
this.tabView.goToPage(pageId);
}
render() {
return (
<View style={{flex: 1}}>
<StatusBar
barStyle='light-content'/>
<ScrollableTabView initialPage={1} renderTabBar={false}
ref={(tabView) => { this.tabView = tabView}}>
<FriendsPage tabView={this.tabView} tabLabel="Friends" />
<ButtonPage tabView={this.tabView} tabLabel="Button" goToPage={ () => this.goToPage(1) } />
<HangoutsPage tabView={this.tabView} tabLabel="Hangouts" />
</ScrollableTabView>
</View>
)
}
}

React-Native Navigation without render command

Is there anyway to redirect user to a different component (also passing arguments with it) without calling render function?
almost in all tutorials i found, they use sameway :
render() {
return (
<NavigatorIOS
style={styles.container}
initialRoute=\{\{
title: 'first',
component: First
}} />
);
}
Now see my code :
in renderRow , for touchablehighlights , i need to be able to redirect user to a page with an argument, (in this case i need to send user to component CourseDetail with argument of course_id, so i can show user course's details)
class Courses extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
}
fetchData() {
// fetching data here
}
componentDidMount() {
this.fetchData();
}
render(){
if (!this.state.loaded) {
return this.renderLoadingView();
}
return (
<View style={{
flex: 1
}}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
/>
</View>
);
}
renderRow(data) {
var header = (
<View>
<View style={styles.rowContainer}>
<View style={styles.textContainer}>
<Text style={styles.title}>{data.nid}</Text>
<Text style={styles.description} numberOfLines={0}>{data.title}</Text>
</View>
</View>
<View style={styles.separator}></View>
</View>
);
///////////
var cid = [];
var content = [];
for(let x=0; x < Object.keys(data.course).length; x++){
cid[x] = data.course[x].course_id;
content.push(
<TouchableHighlight
underlayColor='#e3e0d7'
key={x}
onPress={()=>{console.log(cid[x]);}} //// i need to navigate user to a page with passing arguments (course_id in this case)
style={styles.child}
>
<Text style={styles.child}>
{data.course[x].title}
</Text>
</TouchableHighlight>
);
}
console.log(cid);
var clist = (
<View style={styles.rowContainer}>
{content}
</View>
);
////////////
return (
<Accordion
header={header}
content={clist}
easing="easeOutCubic"
/>
);
}
renderLoadingView() {
return (
<View style={styles.loading}>
<Text style={styles.loading}>
Loading Courses, please wait...
</Text>
</View>
);
}
}
module.exports = Courses;
Thanks in Advance!
By help of this Question here :
React-Native: Cannot access state values or any methods declared from renderRow
I was able to solve the issue by changing :
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
/>
To :
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
style={styles.listView}
/>
Hope it will help others who may have the same problem.

Categories

Resources