Objects are not valid as a React child in React Native - react-native

By rendering the FlatList I always get the error "Objects are not valid as a React child (found: object with keys {dispatchConfig, _targetInst, _dispatchListeners, _dispatchInstances, nativeEvent, type, target, currentTarget, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, isDefaultPrevented, isPropagationStopped}). If you meant to render a collection of children, use an array instead.".
I find out that the rendered item in the Text component needs to be a primitive type but I think it's rendering a string which is a primitive type.
My Code

Welcome to StackOverflow...in the future, please add code as a text snippet to make it easier to use.
The problem is that you are passing objects rather than strings into the courseGoals array. This is because the onChange handler of TextInput takes a whole event object.
Switch it to onChangeText, which passes a string, and it should work.

Related

How to handle changing props inside a component

I'm making a Form wrapper and I'm wondering how to handle data object prop.
From what I have seen out there, there are some (like FormKit) that mutate the prop object that holds the data. This is not a recommended way according to the official docs. Then there are those (like VueFormulate) that create a shallow copy of the data object before emiting the changed object. To support nested data object you need to deep copy the data object on every change. This seems wasteful with large forms.
Is there an alternative where you don't deep copy an object and you don't mutate object prop?
You could possibly use v-model. as the docs will say, it's shorthand for the child component having a property bound from the parent and when a change event occurs you emit an update event from the child to the parent to have the parent update the property, and the child will subsequently sync to the new value.
ie:
childComponent *has value change*
onChange (value) => this.$emit("updateValue", value)
parentComponent *recieved "updateValue" event*
onUpdateValue(value) => this.parentValue = value

Vue, separate out component templates

I have got a rather large template at the moment for my component. I want to separate aspects of this into it's own component.
However i'm struggling to pass data to this component. I still want to be able to manipulate the data within the child and have the data in the parent update. So for example if I pass in an object, and then use v-model within the child on a textbox, the changes should reflex within the parent.
So, i'd assume as I loop through the list of objects I would v-model them into my child component, like so:
Main.vue
<card v-for="quote in quotes" v-model="quote"></card>
And then of course accept the input within the new model:
Card.vue
export default {
props: [ 'input' ]
}
However i'm getting the following error and I can't really make sense of it.
You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-mode
l on an object property instead.

Hows to do nested navigation with react-md?

Looking at the react-md component library, there are clear examples on how to draw a list of navigation items, including with dividers.
However I CAN'T find an example of how to use nested lists such as in the image pasted here. Using the <NavigationDrawer> components, what format should the navItems property be to get a nested list?
The documentation shows that this property should be an array of items that are either react elements or objects.
arrayOf(oneOfType([
element,
shape({
divider: bool,
subheader: bool,
primaryText: node
})
]))
Or... what other combinations of components could work?
The <ListItem> component has a property nestedItems, which results in an expansion list. So it's nothing to do with the <NavigationDrawer> component.

Vue.js global data access with v-model

I am working on a web app where users can work on a project. The structure of the app is as follows:
Component A (app)
Component B1-Bn (header, footer, main window etc., children of A)
Component C1 (Input area; with inputs for the user to work on the project, child of main window)
Component C2 (Output area; canvas which shows the result based on inputs from C1. In the future also a "graphical" input area that syncs with C1. Child of main window)
Component D1-Dn (Single parts of the input area like tables, advanced input components etc. Child of C1)
Now the project that the user is working on consists of an object stored in Component A. Component Dn needs to write to the object in Component A and also C2 in the future.
I can't get the v-model on input components Dn to work. I tried to pass the data from A down to C1 via props / v-bind and then in Dn, I v-model the prop from C1 (which originates from A) to the input-field. I also tried to use the sync modifier without sucess.
I seem to have a lack of understanding of the vue logic. I come from a desktop background where you just define the scope of variables.
I also found that other vue apprentices have the same understanding problem but somehow the answers I found where not sufficient.
I want a "global" variable that can be edited by every component and is linked to elements in the DOM. What would be the best way to achieve this?
Declare your variable at data when creating Vue Object in your root component (Component A) like
var app = new Vue({
data: function(){
return {
showSetting: {}
}
},
})
Now you can access this showSetting variable in any component like
app.showSetting;
//change it in any component
app.showSetting = {a:1,b:2};
//or append new value to object
Object.assign({d:3},app.showSetting);
Thanks for the answers so far. I guess both of them work. I found another solution because now I fully understand how data is passed in vue:Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child component will affect parent state. I will pass all data as arrays in the future, as I only want references. The only question that remains is why the programmer is not allowed to define by himself whether the data is passed by reference or not...
Source: Vue.js Guide

How to properly select from multiple Redux-slices in mapStateToProps?

My Redux store is normalized, i.e. it's quite flat and each entity type has it's own slice.
Here is a simplified example of my Redux store:
drawings
1: {name:'D1', thumbnailId: 33}
2: {name:'D2', thumbnailId: 34}
thumbnails
33: {filePath: 'path to local file'}
34: {filePath: null (i.e. needs to be downloaded)}
The listview that shows the drawings whith respective thumbnail needs to be re-rendered when:
Changes in drawings-slice occurs, i.e. new, removed or updated drawings
Changes in any of the referenced thumbnails occurs, i.e. thumbnail 34 eventually gets downloaded (download is handled async by a Redux-Saga)
My current mapStateToProps is obviously flawed, as it does excessive selections from the Redux store. This happens before the actual view gets hold of its new props, so I cannot control this from shouldComponentUpdate.
There are several places in my app where I need a better solution for this.
Here is my flawed mapStateToProps (I'm using Immutable.js):
(state, ownProps) => {
const drawings = selectProjectDrawings(state, ownProps.projectId).map(drawing => {
const thumbnailFileGuid = drawing.get('thumbnailFileGuid');
if (!thumbnailFileGuid) return drawing;
const filePath = selectFile(state, thumbnailFileGuid).get(THUMBNAIL_FILE_PATH_FIELD);
return filePath ? drawing.set('_thumbnailFilePath', filePath) : drawing;
});
return {
drawings: drawings
};
}
Edit:
A really bad thing with my current solution is that I'm creating new drawing object by augmenting them with _thumbnailPath. This means that I cannot compare the object references in shouldComponentUpdate, as the reference is always altered.
Being able to compare object references is one of the main argument for not mutating the objects, but I have thrown away this opportunity with my flawed solution.
I would suggest placing this logic behind a selector. reselect is a selector memoization library which means that it will do a deep compare of the values for you and if the returned object and all the properties within stay the same, (including deep tree like structures) then it will return the original object.
React then will notice this is the same object instance (not a new one) and not re-render. It is OK if you recreate the drawing object within the selector, since you are not capturing this in any persistent state.
Side note: As your app grows, you will notice that all connected components will get mapStateToProps called even if it has nothing to do with it, therefore using a memoized selector really helps here. Otherwise your componentShouldUpdate gets complex real quick.