To do this, we need to change the way we parse the tiny-props attribute.
New way to parse Tiny-props
If you log attribute in _addProps, you should see two pairs of props.
export default function Tiny (options) {
// ...
function _addProps (comp) {
const attribute = comp.element.getAttribute('tiny-props')
if (!attribute) return
console.log(attribute)
// ...
}
// ...
}
The first value in each pair is the key of the prop.
The second value in each pair is the value we want to pass into the prop.
We need to obtain each pair of values. The simplest way to do this is to remove all brackets and commas. This results in 4 values separated by a space.
We can remove brackets and commas with replace functions.
Replace [ with ''
Replace ] with ''
Replace , with ''
When we use replace we need to pass in a greedy regular expression since we want to find and replace more than one character. To add a greedy regular expression, we add a g flag at the end of the regular expression.
// Example of a greedy regular expression
const regex = /abc/g
Here are the replace functions we need. Notice we escaped [ and ] with a backslash. We do this because square brackets are used to represent something in regular expressions.
Odd values (1st, 3rd, 5th, etc) are keys we want to add to props while even values (2nd, 4th, 6th, etc) are values themselves.
We can loop through the array and extract these values. Here, we’ll use a for-loop so we don’t have to loop through every item. We’ll increase the index by 2 so we can skip one item with each iteration.
export default function Tiny (options) {
// ...
function _addProps (comp) {
// ...
for (let index = 0; index < props.length - 1; index = index + 2) {
const prop = props[index]
let value = props[index + 1]
}
// ...
}
// ...
}
We can now copy-paste the previous code we wrote to obtain the correct value into this loop. Make sure to use continue instead of return since return ends the entire _addProps function while continue only ends the current loop.
export default function Tiny (options) {
// ...
function _addProps (comp) {
// ...
for (let index = 0; index < props.length - 1; index = index + 2) {
const prop = props[index]
let value = props[index + 1]
if (value.includes('.')) {
value = value
.split('.')
.reduce((acc, current) => acc[current], options)
comp.props[prop] = value
continue
}
if (options[value]) {
comp.props[prop] = options[value]
continue
}
comp.props[prop] = value
}
// ...
}
// ...
}
At this point, both parentCount and childCount should both be 10.
But since we hardcoded the childCount value into a custom attribute, this value will turn into a string. This explains why total count is 1010, not 20.
The best way to resolve this problem is to pass childCount via a property. We can do it via state.childCount for example.
At this point you may be thinking: Why are we splitting the whole Counter thing into three components? Wouldn’t it be simpler to put everything in one component?
In this case, yes. It’s much easier to build everything as one component. But don’t forget we’re building a library that allows people to split code up into smaller parts. The example we’re working on is small and trivial. The splitting only begins to shine for larger components.